准备工作

  • 浏览器(建议火狐,分析JS建议都用火狐)
  • 抓包工具(以Fiddler为例)

Fiddler设置好filters(过滤规则),方便分析(这些是我测试出来登录需要请求的域名):

xui.ptlogin2.qq.com;ssl.ptlogin2.qq.com;check.ptlogin2.qq.com

filters

动手

进入登录网页

在Qzone首页,发现登录使用了iframe,我们直接到iframe的链接:
https://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=https%3A//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%3A%2F%2Fqzs.qzone.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=https%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html&pt_no_auth=1
1
2

登录调试

切换到账号密码登录,手动输入账号密码登录一次,抓包,分析参数。

1

分析这些请求,可以发现,对登录有用的请求就是三个,同时我也一个个地给大家试出了哪些参数是有用的,哪些是不必要的。请求过程中要保持 cookies 一致。

请求1

第一个GET请求,用来取得 cookies,cookies中有个pt_login_sig在后面的请求中有用,这里给出过滤掉无意义参数的最终URL:

https://xui.ptlogin2.qq.com/cgi-bin/xlogin?s_url= https://qzs.qq.com/qzone/v5/loginsucc.html?para=izone

请求2

这个也是GET请求,用于返回判断是否需要验证码和第三步要用到的参数,这里再次过滤掉无意义参数,给出最终URL:

http://check.ptlogin2.qq.com/check?pt_tea=2&uin=你的QQ号码&appid=549000912

请求会返回一段数据,第三个请求里要用到:

ptui_checkVC('0','!LJA','\x00\x00\x00\x00\x5d\xab\x1f\xb5','463ae630ab82f5cc28778a616a2574652b2db3e4b05425159fb28f5a8f537bdc8979fd504de6f00a7f96c936e6c5dcdc9d4eb6b2b85378b0','2', 'E6L32pAD2BQ32kjYlPKakQWJ1z48eMNZbyBpbuy0dISQVXkNDtxJwR1vtCP8svu5')

这段数据里,第一个参数表示是否需要验证码,如果需要会返回'1',不需要就返回'0'(需要验证码的话会进入另一种登录模式,这里不提供解决方案,仅讨论不需要验证码的情况)。有用的是第二个和第四个,在本例中就是:验证码!LJA和会话验证463ae630ab82f5cc28778a616a2574652b2db3e4b05425159fb28f5a8f537bdc8979fd504de6f00a7f96c936e6c5dcdc9d4eb6b2b85378b0

请求3

这也是GET请求,这步难度最大的就是加密参数的获取了,因为这里有个参数是你加密后的密码。

我们开始分析JS。

ctrl-shift-C,点击调试器(当有事件发生时会自动断点暂停)。
2
再次手动输入账号密码登录,过程中调试器会自动暂停在事件断点。根据需要F8:恢复,F11:步进。
在发现格式美化后的代码里3632行开始是发送请求的代码。
3
顺藤摸瓜,找到这些里面实现加密密码的JS,我已经找到了,叫$.Encryption,你们可以直接ctrl-F搜索,然后进一步分析,发现还依赖另外两个对象:$.RSATEA,我们直接扒拉下拉就成了。
最终得到实现加密的JS如下:

//这里定义window和navigator的目的是为了方便迁移,到时候在非浏览器环境下也可以运行
window = {};
window.$ = {}
window.$pt = {};
var navigator = {};
navigator.appName = "navigator";
navigator.appVersion = "5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36";

$ = window.$ || {},
  $pt = window.$pt || {},
  $.RSA = $pt.RSA = function() {
    function t(t, e) {
      return new a(t, e)
    }

    function e(t, e) {
      if (e < t.length + 11)
        return uv_alert("Message too long for RSA"),
          null;
      for (var n = new Array, o = t.length - 1; o >= 0 && e > 0;) {
        var i = t.charCodeAt(o--);
        n[--e] = i
      }
      n[--e] = 0;
      for (var r = new Y, p = new Array; e > 2;) {
        for (p[0] = 0; 0 == p[0];)
          r.nextBytes(p);
        n[--e] = p[0]
      }
      return n[--e] = 2,
        n[--e] = 0,
        new a(n)
    }

    function n() {
      this.n = null,
        this.e = 0,
        this.d = null,
        this.p = null,
        this.q = null,
        this.dmp1 = null,
        this.dmq1 = null,
        this.coeff = null
    }

    function o(e, n) {
      null != e && null != n && e.length > 0 && n.length > 0 ? (this.n = t(e, 16),
        this.e = parseInt(n, 16)) : uv_alert("Invalid RSA public key")
    }

    function i(t) {
      return t.modPowInt(this.e, this.n)
    }

    function r(t) {
      var n = e(t, this.n.bitLength() + 7 >> 3);
      if (null == n)
        return null;
      var o = this.doPublic(n);
      if (null == o)
        return null;
      var i = o.toString(16);
      return 0 == (1 & i.length) ? i : "0" + i
    }

    function a(t, e, n) {
      null != t && ("number" == typeof t ? this.fromNumber(t, e, n) : null == e && "string" != typeof t ? this.fromString(t, 256) : this.fromString(t, e))
    }

    function p() {
      return new a(null)
    }

    function s(t, e, n, o, i, r) {
      for (; --r >= 0;) {
        var a = e * this[t++] + n[o] + i;
        i = Math.floor(a / 67108864),
          n[o++] = 67108863 & a
      }
      return i
    }

    function c(t, e, n, o, i, r) {
      for (var a = 32767 & e, p = e >> 15; --r >= 0;) {
        var s = 32767 & this[t],
          c = this[t++] >> 15,
          u = p * s + c * a;
        s = a * s + ((32767 & u) << 15) + n[o] + (1073741823 & i),
          i = (s >>> 30) + (u >>> 15) + p * c + (i >>> 30),
          n[o++] = 1073741823 & s
      }
      return i
    }

    function u(t, e, n, o, i, r) {
      for (var a = 16383 & e, p = e >> 14; --r >= 0;) {
        var s = 16383 & this[t],
          c = this[t++] >> 14,
          u = p * s + c * a;
        s = a * s + ((16383 & u) << 14) + n[o] + i,
          i = (s >> 28) + (u >> 14) + p * c,
          n[o++] = 268435455 & s
      }
      return i
    }

    function l(t) {
      return st.charAt(t)
    }

    function d(t, e) {
      var n = ct[t.charCodeAt(e)];
      return null == n ? -1 : n
    }

    function h(t) {
      for (var e = this.t - 1; e >= 0; --e)
        t[e] = this[e];
      t.t = this.t,
        t.s = this.s
    }

    function f(t) {
      this.t = 1,
        this.s = t < 0 ? -1 : 0,
        t > 0 ? this[0] = t : t < -1 ? this[0] = t + DV : this.t = 0
    }

    function g(t) {
      var e = p();
      return e.fromInt(t),
        e
    }

    function w(t, e) {
      var n;
      if (16 == e)
        n = 4;
      else if (8 == e)
        n = 3;
      else if (256 == e)
        n = 8;
      else if (2 == e)
        n = 1;
      else if (32 == e)
        n = 5;
      else {
        if (4 != e)
          return void this.fromRadix(t, e);
        n = 2
      }
      this.t = 0,
        this.s = 0;
      for (var o = t.length, i = !1, r = 0; --o >= 0;) {
        var p = 8 == n ? 255 & t[o] : d(t, o);
        p < 0 ? "-" == t.charAt(o) && (i = !0) : (i = !1,
          0 == r ? this[this.t++] = p : r + n > this.DB ? (this[this.t - 1] |= (p & (1 << this.DB - r) - 1) << r,
            this[this.t++] = p >> this.DB - r) : this[this.t - 1] |= p << r,
          (r += n) >= this.DB && (r -= this.DB))
      }
      8 == n && 0 != (128 & t[0]) && (this.s = -1,
          r > 0 && (this[this.t - 1] |= (1 << this.DB - r) - 1 << r)),
        this.clamp(),
        i && a.ZERO.subTo(this, this)
    }

    function m() {
      for (var t = this.s & this.DM; this.t > 0 && this[this.t - 1] == t;)
        --this.t
    }

    function _(t) {
      if (this.s < 0)
        return "-" + this.negate().toString(t);
      var e;
      if (16 == t)
        e = 4;
      else if (8 == t)
        e = 3;
      else if (2 == t)
        e = 1;
      else if (32 == t)
        e = 5;
      else {
        if (4 != t)
          return this.toRadix(t);
        e = 2
      }
      var n, o = (1 << e) - 1,
        i = !1,
        r = "",
        a = this.t,
        p = this.DB - a * this.DB % e;
      if (a-- > 0)
        for (p < this.DB && (n = this[a] >> p) > 0 && (i = !0,
            r = l(n)); a >= 0;)
          p < e ? (n = (this[a] & (1 << p) - 1) << e - p,
            n |= this[--a] >> (p += this.DB - e)) : (n = this[a] >> (p -= e) & o,
            p <= 0 && (p += this.DB,
              --a)),
          n > 0 && (i = !0),
          i && (r += l(n));
      return i ? r : "0"
    }

    function v() {
      var t = p();
      return a.ZERO.subTo(this, t),
        t
    }

    function y() {
      return this.s < 0 ? this.negate() : this
    }

    function b(t) {
      var e = this.s - t.s;
      if (0 != e)
        return e;
      var n = this.t;
      if (0 != (e = n - t.t))
        return e;
      for (; --n >= 0;)
        if (0 != (e = this[n] - t[n]))
          return e;
      return 0
    }

    function $(t) {
      var e, n = 1;
      return 0 != (e = t >>> 16) && (t = e,
          n += 16),
        0 != (e = t >> 8) && (t = e,
          n += 8),
        0 != (e = t >> 4) && (t = e,
          n += 4),
        0 != (e = t >> 2) && (t = e,
          n += 2),
        0 != (e = t >> 1) && (t = e,
          n += 1),
        n
    }

    function k() {
      return this.t <= 0 ? 0 : this.DB * (this.t - 1) + $(this[this.t - 1] ^ this.s & this.DM)
    }

    function q(t, e) {
      var n;
      for (n = this.t - 1; n >= 0; --n)
        e[n + t] = this[n];
      for (n = t - 1; n >= 0; --n)
        e[n] = 0;
      e.t = this.t + t,
        e.s = this.s
    }

    function S(t, e) {
      for (var n = t; n < this.t; ++n)
        e[n - t] = this[n];
      e.t = Math.max(this.t - t, 0),
        e.s = this.s
    }

    function T(t, e) {
      var n, o = t % this.DB,
        i = this.DB - o,
        r = (1 << i) - 1,
        a = Math.floor(t / this.DB),
        p = this.s << o & this.DM;
      for (n = this.t - 1; n >= 0; --n)
        e[n + a + 1] = this[n] >> i | p,
        p = (this[n] & r) << o;
      for (n = a - 1; n >= 0; --n)
        e[n] = 0;
      e[a] = p,
        e.t = this.t + a + 1,
        e.s = this.s,
        e.clamp()
    }

    function I(t, e) {
      e.s = this.s;
      var n = Math.floor(t / this.DB);
      if (n >= this.t)
        return void(e.t = 0);
      var o = t % this.DB,
        i = this.DB - o,
        r = (1 << o) - 1;
      e[0] = this[n] >> o;
      for (var a = n + 1; a < this.t; ++a)
        e[a - n - 1] |= (this[a] & r) << i,
        e[a - n] = this[a] >> o;
      o > 0 && (e[this.t - n - 1] |= (this.s & r) << i),
        e.t = this.t - n,
        e.clamp()
    }

    function A(t, e) {
      for (var n = 0, o = 0, i = Math.min(t.t, this.t); n < i;)
        o += this[n] - t[n],
        e[n++] = o & this.DM,
        o >>= this.DB;
      if (t.t < this.t) {
        for (o -= t.s; n < this.t;)
          o += this[n],
          e[n++] = o & this.DM,
          o >>= this.DB;
        o += this.s
      } else {
        for (o += this.s; n < t.t;)
          o -= t[n],
          e[n++] = o & this.DM,
          o >>= this.DB;
        o -= t.s
      }
      e.s = o < 0 ? -1 : 0,
        o < -1 ? e[n++] = this.DV + o : o > 0 && (e[n++] = o),
        e.t = n,
        e.clamp()
    }

    function E(t, e) {
      var n = this.abs(),
        o = t.abs(),
        i = n.t;
      for (e.t = i + o.t; --i >= 0;)
        e[i] = 0;
      for (i = 0; i < o.t; ++i)
        e[i + n.t] = n.am(0, o[i], e, i, 0, n.t);
      e.s = 0,
        e.clamp(),
        this.s != t.s && a.ZERO.subTo(e, e)
    }

    function C(t) {
      for (var e = this.abs(), n = t.t = 2 * e.t; --n >= 0;)
        t[n] = 0;
      for (n = 0; n < e.t - 1; ++n) {
        var o = e.am(n, e[n], t, 2 * n, 0, 1);
        (t[n + e.t] += e.am(n + 1, 2 * e[n], t, 2 * n + 1, o, e.t - n - 1)) >= e.DV && (t[n + e.t] -= e.DV,
          t[n + e.t + 1] = 1)
      }
      t.t > 0 && (t[t.t - 1] += e.am(n, e[n], t, 2 * n, 0, 1)),
        t.s = 0,
        t.clamp()
    }

    function D(t, e, n) {
      var o = t.abs();
      if (!(o.t <= 0)) {
        var i = this.abs();
        if (i.t < o.t)
          return null != e && e.fromInt(0),
            void(null != n && this.copyTo(n));
        null == n && (n = p());
        var r = p(),
          s = this.s,
          c = t.s,
          u = this.DB - $(o[o.t - 1]);
        u > 0 ? (o.lShiftTo(u, r),
          i.lShiftTo(u, n)) : (o.copyTo(r),
          i.copyTo(n));
        var l = r.t,
          d = r[l - 1];
        if (0 != d) {
          var h = d * (1 << this.F1) + (l > 1 ? r[l - 2] >> this.F2 : 0),
            f = this.FV / h,
            g = (1 << this.F1) / h,
            w = 1 << this.F2,
            m = n.t,
            _ = m - l,
            v = null == e ? p() : e;
          for (r.dlShiftTo(_, v),
            n.compareTo(v) >= 0 && (n[n.t++] = 1,
              n.subTo(v, n)),
            a.ONE.dlShiftTo(l, v),
            v.subTo(r, r); r.t < l;)
            r[r.t++] = 0;
          for (; --_ >= 0;) {
            var y = n[--m] == d ? this.DM : Math.floor(n[m] * f + (n[m - 1] + w) * g);
            if ((n[m] += r.am(0, y, n, _, 0, l)) < y)
              for (r.dlShiftTo(_, v),
                n.subTo(v, n); n[m] < --y;)
                n.subTo(v, n)
          }
          null != e && (n.drShiftTo(l, e),
              s != c && a.ZERO.subTo(e, e)),
            n.t = l,
            n.clamp(),
            u > 0 && n.rShiftTo(u, n),
            s < 0 && a.ZERO.subTo(n, n)
        }
      }
    }

    function L(t) {
      var e = p();
      return this.abs().divRemTo(t, null, e),
        this.s < 0 && e.compareTo(a.ZERO) > 0 && t.subTo(e, e),
        e
    }

    function M(t) {
      this.m = t
    }

    function x(t) {
      return t.s < 0 || t.compareTo(this.m) >= 0 ? t.mod(this.m) : t
    }

    function B(t) {
      return t
    }

    function O(t) {
      t.divRemTo(this.m, null, t)
    }

    function R(t, e, n) {
      t.multiplyTo(e, n),
        this.reduce(n)
    }

    function H(t, e) {
      t.squareTo(e),
        this.reduce(e)
    }

    function K() {
      if (this.t < 1)
        return 0;
      var t = this[0];
      if (0 == (1 & t))
        return 0;
      var e = 3 & t;
      return e = e * (2 - (15 & t) * e) & 15,
        e = e * (2 - (255 & t) * e) & 255,
        e = e * (2 - ((65535 & t) * e & 65535)) & 65535,
        e = e * (2 - t * e % this.DV) % this.DV,
        e > 0 ? this.DV - e : -e
    }

    function U(t) {
      this.m = t,
        this.mp = t.invDigit(),
        this.mpl = 32767 & this.mp,
        this.mph = this.mp >> 15,
        this.um = (1 << t.DB - 15) - 1,
        this.mt2 = 2 * t.t
    }

    function N(t) {
      var e = p();
      return t.abs().dlShiftTo(this.m.t, e),
        e.divRemTo(this.m, null, e),
        t.s < 0 && e.compareTo(a.ZERO) > 0 && this.m.subTo(e, e),
        e
    }

    function P(t) {
      var e = p();
      return t.copyTo(e),
        this.reduce(e),
        e
    }

    function Q(t) {
      for (; t.t <= this.mt2;)
        t[t.t++] = 0;
      for (var e = 0; e < this.m.t; ++e) {
        var n = 32767 & t[e],
          o = n * this.mpl + ((n * this.mph + (t[e] >> 15) * this.mpl & this.um) << 15) & t.DM;
        for (n = e + this.m.t,
          t[n] += this.m.am(0, o, t, e, 0, this.m.t); t[n] >= t.DV;)
          t[n] -= t.DV,
          t[++n]++
      }
      t.clamp(),
        t.drShiftTo(this.m.t, t),
        t.compareTo(this.m) >= 0 && t.subTo(this.m, t)
    }

    function j(t, e) {
      t.squareTo(e),
        this.reduce(e)
    }

    function F(t, e, n) {
      t.multiplyTo(e, n),
        this.reduce(n)
    }

    function V() {
      return 0 == (this.t > 0 ? 1 & this[0] : this.s)
    }

    function z(t, e) {
      if (t > 4294967295 || t < 1)
        return a.ONE;
      var n = p(),
        o = p(),
        i = e.convert(this),
        r = $(t) - 1;
      for (i.copyTo(n); --r >= 0;)
        if (e.sqrTo(n, o),
          (t & 1 << r) > 0)
          e.mulTo(o, i, n);
        else {
          var s = n;
          n = o,
            o = s
        }
      return e.revert(n)
    }

    function G(t, e) {
      var n;
      return n = t < 256 || e.isEven() ? new M(e) : new U(e),
        this.exp(t, n)
    }

    function J(t) {
      lt[dt++] ^= 255 & t,
        lt[dt++] ^= t >> 8 & 255,
        lt[dt++] ^= t >> 16 & 255,
        lt[dt++] ^= t >> 24 & 255,
        dt >= gt && (dt -= gt)
    }

    function W() {
      //J((new Date).getTime())
      J(1539492088527)
    }

    function X() {
      if (null == ut) {
        for (W(),
          ut = ot(),
          ut.init(lt),
          dt = 0; dt < lt.length; ++dt)
          lt[dt] = 0;
        dt = 0
      }
      return ut.next()
    }

    function Z(t) {
      var e;
      for (e = 0; e < t.length; ++e)
        t[e] = X()
    }

    function Y() {}

    function tt() {
      this.i = 0,
        this.j = 0,
        this.S = new Array
    }

    function et(t) {
      var e, n, o;
      for (e = 0; e < 256; ++e)
        this.S[e] = e;
      for (n = 0,
        e = 0; e < 256; ++e)
        n = n + this.S[e] + t[e % t.length] & 255,
        o = this.S[e],
        this.S[e] = this.S[n],
        this.S[n] = o;
      this.i = 0,
        this.j = 0
    }

    function nt() {
      var t;
      return this.i = this.i + 1 & 255,
        this.j = this.j + this.S[this.i] & 255,
        t = this.S[this.i],
        this.S[this.i] = this.S[this.j],
        this.S[this.j] = t,
        this.S[t + this.S[this.i] & 255]
    }

    function ot() {
      return new tt
    }

    function it(t, e, o) {
      e = "e9a815ab9d6e86abbf33a4ac64e9196d5be44a09bd0ed6ae052914e1a865ac8331fed863de8ea697e9a7f63329e5e23cda09c72570f46775b7e39ea9670086f847d3c9c51963b131409b1e04265d9747419c635404ca651bbcbc87f99b8008f7f5824653e3658be4ba73e4480156b390bb73bc1f8b33578e7a4e12440e9396f2552c1aff1c92e797ebacdc37c109ab7bce2367a19c56a033ee04534723cc2558cb27368f5b9d32c04d12dbd86bbd68b1d99b7c349a8453ea75d1b2e94491ab30acf6c46a36a75b721b312bedf4e7aad21e54e9bcbcf8144c79b6e3c05eb4a1547750d224c0085d80e6da3907c3d945051c13c7c1dcefd6520ee8379c4f5231ed",
        o = "10001";
      var i = new n;
      return i.setPublic(e, o),
        i.encrypt(t)
    }
    n.prototype.doPublic = i,
      n.prototype.setPublic = o,
      n.prototype.encrypt = r;
    var rt;
    "Microsoft Internet Explorer" == navigator.appName ? (a.prototype.am = c,
        rt = 30) : "Netscape" != navigator.appName ? (a.prototype.am = s,
        rt = 26) : (a.prototype.am = u,
        rt = 28),
      a.prototype.DB = rt,
      a.prototype.DM = (1 << rt) - 1,
      a.prototype.DV = 1 << rt;
    a.prototype.FV = Math.pow(2, 52),
      a.prototype.F1 = 52 - rt,
      a.prototype.F2 = 2 * rt - 52;
    var at, pt, st = "0123456789abcdefghijklmnopqrstuvwxyz",
      ct = new Array;
    for (at = "0".charCodeAt(0),
      pt = 0; pt <= 9; ++pt)
      ct[at++] = pt;
    for (at = "a".charCodeAt(0),
      pt = 10; pt < 36; ++pt)
      ct[at++] = pt;
    for (at = "A".charCodeAt(0),
      pt = 10; pt < 36; ++pt)
      ct[at++] = pt;
    M.prototype.convert = x,
      M.prototype.revert = B,
      M.prototype.reduce = O,
      M.prototype.mulTo = R,
      M.prototype.sqrTo = H,
      U.prototype.convert = N,
      U.prototype.revert = P,
      U.prototype.reduce = Q,
      U.prototype.mulTo = F,
      U.prototype.sqrTo = j,
      a.prototype.copyTo = h,
      a.prototype.fromInt = f,
      a.prototype.fromString = w,
      a.prototype.clamp = m,
      a.prototype.dlShiftTo = q,
      a.prototype.drShiftTo = S,
      a.prototype.lShiftTo = T,
      a.prototype.rShiftTo = I,
      a.prototype.subTo = A,
      a.prototype.multiplyTo = E,
      a.prototype.squareTo = C,
      a.prototype.divRemTo = D,
      a.prototype.invDigit = K,
      a.prototype.isEven = V,
      a.prototype.exp = z,
      a.prototype.toString = _,
      a.prototype.negate = v,
      a.prototype.abs = y,
      a.prototype.compareTo = b,
      a.prototype.bitLength = k,
      a.prototype.mod = L,
      a.prototype.modPowInt = G,
      a.ZERO = g(0),
      a.ONE = g(1);
    var ut, lt, dt;
    if (null == lt) {
      lt = new Array,
        dt = 0;
      var ht;
      if ("Netscape" == navigator.appName && navigator.appVersion < "5" && window.crypto && window.crypto.random) {
        var ft = window.crypto.random(32);
        for (ht = 0; ht < ft.length; ++ht)
          lt[dt++] = 255 & ft.charCodeAt(ht)
      }
      for (; dt < gt;)
        ht = Math.floor(65536 * Math.random()),
        lt[dt++] = ht >>> 8,
        lt[dt++] = 255 & ht;
      dt = 0,
        W()
    }
    Y.prototype.nextBytes = Z,
      tt.prototype.init = et,
      tt.prototype.next = nt;
    var gt = 256;
    return {
      rsa_encrypt: it
    }
  }(),
  function(t) {
    function e() {
      //return Math.round(4294967295 * Math.random())
      return 1;
    }

    function n(t, e, n) {
      (!n || n > 4) && (n = 4);
      for (var o = 0, i = e; i < e + n; i++)
        o <<= 8,
        o |= t[i];
      return (4294967295 & o) >>> 0
    }

    function o(t, e, n) {
      t[e + 3] = n >> 0 & 255,
        t[e + 2] = n >> 8 & 255,
        t[e + 1] = n >> 16 & 255,
        t[e + 0] = n >> 24 & 255
    }

    function i(t) {
      if (!t)
        return "";
      for (var e = "", n = 0; n < t.length; n++) {
        var o = Number(t[n]).toString(16);
        1 == o.length && (o = "0" + o),
          e += o
      }
      return e
    }

    function r(t) {
      for (var e = "", n = 0; n < t.length; n += 2)
        e += String.fromCharCode(parseInt(t.substr(n, 2), 16));
      return e
    }

    function a(t, e) {
      if (!t)
        return "";
      e && (t = p(t));
      for (var n = [], o = 0; o < t.length; o++)
        n[o] = t.charCodeAt(o);
      return i(n)
    }

    function p(t) {
      var e, n, o = [],
        i = t.length;
      for (e = 0; e < i; e++)
        n = t.charCodeAt(e),
        n > 0 && n <= 127 ? o.push(t.charAt(e)) : n >= 128 && n <= 2047 ? o.push(String.fromCharCode(192 | n >> 6 & 31), String.fromCharCode(128 | 63 & n)) : n >= 2048 && n <= 65535 && o.push(String.fromCharCode(224 | n >> 12 & 15), String.fromCharCode(128 | n >> 6 & 63), String.fromCharCode(128 | 63 & n));
      return o.join("")
    }

    function s(t) {
      m = new Array(8),
        _ = new Array(8),
        v = y = 0,
        k = !0,
        w = 0;
      var n = t.length,
        o = 0;
      w = (n + 10) % 8,
        0 != w && (w = 8 - w),
        b = new Array(n + w + 10),
        m[0] = 255 & (248 & e() | w);
      for (var i = 1; i <= w; i++)
        m[i] = 255 & e();
      w++;
      for (var i = 0; i < 8; i++)
        _[i] = 0;
      for (o = 1; o <= 2;)
        w < 8 && (m[w++] = 255 & e(),
          o++),
        8 == w && u();
      for (var i = 0; n > 0;)
        w < 8 && (m[w++] = t[i++],
          n--),
        8 == w && u();
      for (o = 1; o <= 7;)
        w < 8 && (m[w++] = 0,
          o++),
        8 == w && u();
      return b
    }

    function c(t) {
      var e = 0,
        n = new Array(8),
        o = t.length;
      if ($ = t,
        o % 8 != 0 || o < 16)
        return null;
      if (_ = d(t),
        w = 7 & _[0],
        (e = o - w - 10) < 0)
        return null;
      for (var i = 0; i < n.length; i++)
        n[i] = 0;
      b = new Array(e),
        y = 0,
        v = 8,
        w++;
      for (var r = 1; r <= 2;)
        if (w < 8 && (w++,
            r++),
          8 == w && (n = t,
            !h()))
          return null;
      for (var i = 0; 0 != e;)
        if (w < 8 && (b[i] = 255 & (n[y + w] ^ _[w]),
            i++,
            e--,
            w++),
          8 == w && (n = t,
            y = v - 8,
            !h()))
          return null;
      for (r = 1; r < 8; r++) {
        if (w < 8) {
          if (0 != (n[y + w] ^ _[w]))
            return null;
          w++
        }
        if (8 == w && (n = t,
            y = v,
            !h()))
          return null
      }
      return b
    }

    function u() {
      for (var t = 0; t < 8; t++)
        m[t] ^= k ? _[t] : b[y + t];
      for (var e = l(m), t = 0; t < 8; t++)
        b[v + t] = e[t] ^ _[t],
        _[t] = m[t];
      y = v,
        v += 8,
        w = 0,
        k = !1
    }

    function l(t) {
      for (var e = 16, i = n(t, 0, 4), r = n(t, 4, 4), a = n(g, 0, 4), p = n(g, 4, 4), s = n(g, 8, 4), c = n(g, 12, 4), u = 0; e-- > 0;)
        u += 2654435769,
        u = (4294967295 & u) >>> 0,
        i += (r << 4) + a ^ r + u ^ (r >>> 5) + p,
        i = (4294967295 & i) >>> 0,
        r += (i << 4) + s ^ i + u ^ (i >>> 5) + c,
        r = (4294967295 & r) >>> 0;
      var l = new Array(8);
      return o(l, 0, i),
        o(l, 4, r),
        l
    }

    function d(t) {
      for (var e = 16, i = n(t, 0, 4), r = n(t, 4, 4), a = n(g, 0, 4), p = n(g, 4, 4), s = n(g, 8, 4), c = n(g, 12, 4), u = 3816266640; e-- > 0;)
        r -= (i << 4) + s ^ i + u ^ (i >>> 5) + c,
        r = (4294967295 & r) >>> 0,
        i -= (r << 4) + a ^ r + u ^ (r >>> 5) + p,
        i = (4294967295 & i) >>> 0,
        u -= 2654435769,
        u = (4294967295 & u) >>> 0;
      var l = new Array(8);
      return o(l, 0, i),
        o(l, 4, r),
        l
    }

    function h() {
      for (var t = ($.length,
          0); t < 8; t++)
        _[t] ^= $[v + t];
      return _ = d(_),
        v += 8,
        w = 0,
        !0
    }

    function f(t, e) {
      var n = [];
      if (e)
        for (var o = 0; o < t.length; o++)
          n[o] = 255 & t.charCodeAt(o);
      else
        for (var i = 0, o = 0; o < t.length; o += 2)
          n[i++] = parseInt(t.substr(o, 2), 16);
      return n
    }
    var g = "",
      w = 0,
      m = [],
      _ = [],
      v = 0,
      y = 0,
      b = [],
      $ = [],
      k = !0;
    t.TEA = {
      encrypt: function(t, e) {
        return i(s(f(t, e)))
      },
      enAsBase64: function(t, e) {
        for (var n = f(t, e), o = s(n), i = "", r = 0; r < o.length; r++)
          i += String.fromCharCode(o[r]);
        return window.btoa(i)
      },
      decrypt: function(t) {
        return i(c(f(t, !1)))
      },
      initkey: function(t, e) {
        g = f(t, e)
      },
      bytesToStr: r,
      strToBytes: a,
      bytesInStr: i,
      dataFromStr: f
    };
    var q = {};
    q.PADCHAR = "=",
      q.ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
      q.getbyte = function(t, e) {
        var n = t.charCodeAt(e);
        if (n > 255)
          throw "INVALID_CHARACTER_ERR: DOM Exception 5";
        return n
      },
      q.encode = function(t) {
        if (1 != arguments.length)
          throw "SyntaxError: Not enough arguments";
        var e, n, o = q.PADCHAR,
          i = q.ALPHA,
          r = q.getbyte,
          a = [];
        t = "" + t;
        var p = t.length - t.length % 3;
        if (0 == t.length)
          return t;
        for (e = 0; e < p; e += 3)
          n = r(t, e) << 16 | r(t, e + 1) << 8 | r(t, e + 2),
          a.push(i.charAt(n >> 18)),
          a.push(i.charAt(n >> 12 & 63)),
          a.push(i.charAt(n >> 6 & 63)),
          a.push(i.charAt(63 & n));
        switch (t.length - p) {
          case 1:
            n = r(t, e) << 16,
              a.push(i.charAt(n >> 18) + i.charAt(n >> 12 & 63) + o + o);
            break;
          case 2:
            n = r(t, e) << 16 | r(t, e + 1) << 8,
              a.push(i.charAt(n >> 18) + i.charAt(n >> 12 & 63) + i.charAt(n >> 6 & 63) + o)
        }
        return a.join("")
      },
      window.btoa = q.encode
  }(window),
  $ = window.$ || {},
  $pt = window.$pt || {}, $.Encryption = $pt.Encryption = function() {
    function t(t) {
      return e(t)
    }

    function e(t) {
      return u(i(c(t), t.length * m))
    }

    function i(t, e) {
      t[e >> 5] |= 128 << e % 32, t[14 + (e + 64 >>> 9 << 4)] = e;
      for (var i = 1732584193, n = -271733879, l = -1732584194, c = 271733878, u = 0; u < t.length; u += 16) {
        var g = i,
          d = n,
          h = l,
          f = c;
        i = o(i, n, l, c, t[u + 0], 7, -680876936), c = o(c, i, n, l, t[u + 1], 12, -389564586), l = o(l, c, i, n, t[u + 2], 17, 606105819), n = o(n, l, c, i, t[u + 3], 22, -1044525330), i = o(i, n, l, c, t[u + 4], 7, -176418897), c = o(c, i, n, l, t[u + 5], 12, 1200080426), l = o(l, c, i, n, t[u + 6], 17, -1473231341), n = o(n, l, c, i, t[u + 7], 22, -45705983), i = o(i, n, l, c, t[u + 8], 7, 1770035416), c = o(c, i, n, l, t[u + 9], 12, -1958414417), l = o(l, c, i, n, t[u + 10], 17, -42063), n = o(n, l, c, i, t[u + 11], 22, -1990404162), i = o(i, n, l, c, t[u + 12], 7, 1804603682), c = o(c, i, n, l, t[u + 13], 12, -40341101), l = o(l, c, i, n, t[u + 14], 17, -1502002290), n = o(n, l, c, i, t[u + 15], 22, 1236535329), i = p(i, n, l, c, t[u + 1], 5, -165796510), c = p(c, i, n, l, t[u + 6], 9, -1069501632), l = p(l, c, i, n, t[u + 11], 14, 643717713), n = p(n, l, c, i, t[u + 0], 20, -373897302), i = p(i, n, l, c, t[u + 5], 5, -701558691), c = p(c, i, n, l, t[u + 10], 9, 38016083), l = p(l, c, i, n, t[u + 15], 14, -660478335), n = p(n, l, c, i, t[u + 4], 20, -405537848), i = p(i, n, l, c, t[u + 9], 5, 568446438), c = p(c, i, n, l, t[u + 14], 9, -1019803690), l = p(l, c, i, n, t[u + 3], 14, -187363961), n = p(n, l, c, i, t[u + 8], 20, 1163531501), i = p(i, n, l, c, t[u + 13], 5, -1444681467), c = p(c, i, n, l, t[u + 2], 9, -51403784), l = p(l, c, i, n, t[u + 7], 14, 1735328473), n = p(n, l, c, i, t[u + 12], 20, -1926607734), i = r(i, n, l, c, t[u + 5], 4, -378558), c = r(c, i, n, l, t[u + 8], 11, -2022574463), l = r(l, c, i, n, t[u + 11], 16, 1839030562), n = r(n, l, c, i, t[u + 14], 23, -35309556), i = r(i, n, l, c, t[u + 1], 4, -1530992060), c = r(c, i, n, l, t[u + 4], 11, 1272893353), l = r(l, c, i, n, t[u + 7], 16, -155497632), n = r(n, l, c, i, t[u + 10], 23, -1094730640), i = r(i, n, l, c, t[u + 13], 4, 681279174), c = r(c, i, n, l, t[u + 0], 11, -358537222), l = r(l, c, i, n, t[u + 3], 16, -722521979), n = r(n, l, c, i, t[u + 6], 23, 76029189), i = r(i, n, l, c, t[u + 9], 4, -640364487), c = r(c, i, n, l, t[u + 12], 11, -421815835), l = r(l, c, i, n, t[u + 15], 16, 530742520), n = r(n, l, c, i, t[u + 2], 23, -995338651), i = s(i, n, l, c, t[u + 0], 6, -198630844), c = s(c, i, n, l, t[u + 7], 10, 1126891415), l = s(l, c, i, n, t[u + 14], 15, -1416354905), n = s(n, l, c, i, t[u + 5], 21, -57434055), i = s(i, n, l, c, t[u + 12], 6, 1700485571), c = s(c, i, n, l, t[u + 3], 10, -1894986606), l = s(l, c, i, n, t[u + 10], 15, -1051523), n = s(n, l, c, i, t[u + 1], 21, -2054922799), i = s(i, n, l, c, t[u + 8], 6, 1873313359), c = s(c, i, n, l, t[u + 15], 10, -30611744), l = s(l, c, i, n, t[u + 6], 15, -1560198380), n = s(n, l, c, i, t[u + 13], 21, 1309151649), i = s(i, n, l, c, t[u + 4], 6, -145523070), c = s(c, i, n, l, t[u + 11], 10, -1120210379), l = s(l, c, i, n, t[u + 2], 15, 718787259), n = s(n, l, c, i, t[u + 9], 21, -343485551), i = a(i, g), n = a(n, d), l = a(l, h), c = a(c, f)
      }
      return 16 == v ? Array(n, l) : Array(i, n, l, c)
    }

    function n(t, e, i, n, o, p) {
      return a(l(a(a(e, t), a(n, p)), o), i)
    }

    function o(t, e, i, o, p, r, s) {
      return n(e & i | ~e & o, t, e, p, r, s)
    }

    function p(t, e, i, o, p, r, s) {
      return n(e & o | i & ~o, t, e, p, r, s)
    }

    function r(t, e, i, o, p, r, s) {
      return n(e ^ i ^ o, t, e, p, r, s)
    }

    function s(t, e, i, o, p, r, s) {
      return n(i ^ (e | ~o), t, e, p, r, s)
    }

    function a(t, e) {
      var i = (65535 & t) + (65535 & e);
      return (t >> 16) + (e >> 16) + (i >> 16) << 16 | 65535 & i
    }

    function l(t, e) {
      return t << e | t >>> 32 - e
    }

    function c(t) {
      for (var e = Array(), i = (1 << m) - 1, n = 0; n < t.length * m; n += m) e[n >> 5] |= (t.charCodeAt(n / m) & i) << n % 32;
      return e
    }

    function u(t) {
      for (var e = _ ? "0123456789ABCDEF" : "0123456789abcdef", i = "", n = 0; n < 4 * t.length; n++) i += e.charAt(t[n >> 2] >> n % 4 * 8 + 4 & 15) + e.charAt(t[n >> 2] >> n % 4 * 8 & 15);
      return i
    }

    function g(t) {
      for (var e = [], i = 0; i < t.length; i += 2) e.push(String.fromCharCode(parseInt(t.substr(i, 2), 16)));
      return e.join("")
    }

    function d(t, e) {
      if (!(Math.random() > (e || 1))) try {
        var i = location.protocol + "//ui.ptlogin2.qq.com/cgi-bin/report?id=" + t;
        document.createElement("img").src = i
      } catch (t) {}
    }

    function h(e, i, n, o) {
      n = n || "", e = e || "";
      for (var p = o ? e : t(e), r = g(p), s = t(r + i), a = window.TEA.strToBytes(n.toUpperCase(), !0), l = Number(a.length / 2).toString(16); l.length < 4;) l = "0" + l;
      window.TEA.initkey(s);
      var c = window.TEA.encrypt(p + window.TEA.strToBytes(i) + l + a);
      window.TEA.initkey("");
      for (var u = Number(c.length / 2).toString(16); u.length < 4;) u = "0" + u;
      var h = $pt.RSA.rsa_encrypt(g(u + c));
      return d(488358, 1), window.btoa(g(h)).replace(/[\/\+=]/g, function(t) {
        return {
          "/": "-",
          "+": "*",
          "=": "_"
        } [t]
      })
    }

    function f(e, i, n) {
      var o = n ? e : t(e),
        p = o + i.toUpperCase();
      return $.RSA.rsa_encrypt(p)
    }
    var _ = 1,
      m = 8,
      v = 32;
    return {
      getEncryption: h,
      getRSAEncryption: f,
      md5: t
    }
  }();

//这个就是最终实现加密密码的函数了,可以直接调用完成加密
function encrypt(p, salt, vc) {
  return $.Encryption.getEncryption(p, salt, vc, false);
}

因为考虑到很多小伙伴可能在其他语言环境下调用JS获取加密后的密码可能有困难,这里我做了个PHP接口,需要调用联系我。

同样我去掉了无用参数,最终URL如下:

https://ssl.ptlogin2.qq.com/login?u=你的QQ号&verifycode=第二个请求获取到的验证码&pt_verifysession_v1=第二个请求获取到的会话验证&p=加密后的密码&pt_randsalt=2&u1=https://qzs.qzone.qq.com/qzone/v5/loginsucc.html?para=izone&from_ui=1&pt_uistyle=40&aid=549000912

提交完最后一个请求,可以看到返回值:

ptuiCB('0','0','https://ptlogin2.qzone.qq.com/check_sig?一段参数','0','登录成功!', 'undefined')

返回值第三个参数链接还需要GET一下才算是正式登陆成功

请求4

把请求 3 的第 3 个参数GET一下,就算登陆成功了。

GET https://ptlogin2.qzone.qq.com/check_sig?一段参数

至此,我们实现了登录,剩下带着你的 cookies 该干啥干啥去icon_rolleyes.png

Cookies筛除

这里对 cookies 也做了测试,帮助大家去掉不必要的 cookies。经过测试,用于维持登陆状态的 cookies 只有以下 4 个:

  • skey
  • uin
  • p_skey
  • p_uin

而其中uinp_uin的值是一样的。


相关文章

  • g_tk参数获取

最后修改:2019 年 10 月 03 日 05 : 00 PM
如果觉得我的文章对你有用,请随意赞赏