<python爬虫之JS逆向实例-1>新浪网

声明:本文只作学习研究,禁止用于非法用途,否则后果自负,如有侵犯了您的合法权益,请告知,我将及时更正、删除,谢谢。邮箱地址:[email protected]


文章目录:

一、项目准备

二、参数分析

三、静态调试

四、动态调试

五、堆栈跟踪

一、项目准备

作者环境:win10,node.js 

开发工具:WebStorm

目标网址: aHR0cHM6Ly93d3cuc2luYS5jb20uY24v 

二、参数分析

    点击登录过后浏览器捕获到了多个数据包,我们可以通过响应内容中的数据判定那个才是我们想要的。

https://login---.com.cn--脱敏处理---1647765920689

<python爬虫之JS逆向实例-1>新浪网_第1张图片

图1

     对于做登录分析的话,我们如何快速找到那个才是我们想要的数据包呢,根据我的个人经验总结①对于登录数据传输绝大部分都是POST请求②数据包名称中包含login这样的关键词③查看响应内容

    接下来我们继续,我们顺利的根据上面的分析找到了响应内容如图2所示,内容的字符进行了unicode编码,我们做一个在线解码查看结果。可以看到对应的就是,登录名或密码错误

<python爬虫之JS逆向实例-1>新浪网_第2张图片

图2

<python爬虫之JS逆向实例-1>新浪网_第3张图片

图3

    查看参数根据经验发现四个可疑参数su、servertime、nonce、sp

<python爬虫之JS逆向实例-1>新浪网_第4张图片

图4

三、静态调试

    经过静态分析调试我们知道了参数加密位置,在代码的名称道中我们也可以看到一些很熟悉的面孔,例如base64\RSAkey\setPublic在里面还掺杂着username\password这样的参数因此我们可以初步判断这就是加密位置,加密的算法是密码学中的RSA非对称加密。

<python爬虫之JS逆向实例-1>新浪网_第5张图片

图5

四、动态调试

    通过断点动态调试我们可以发现,我们的账号和密码都是在这个位置进行加密的,对于username的结果我们是可以直接和图4中完全吻合的,密码部分是因为RAS加密的特性他的结果必然是对不上的,我们暂时可以忽略。

<python爬虫之JS逆向实例-1>新浪网_第6张图片

图6

五、堆栈跟踪(根据加密参数进行图解,加密代码全部做了脱敏处理,只截取了关键部分)-想要进一步了解学习可以在公众号留言

--------------------------su加密--------------------------

1.su - 针对账号进行加密

<python爬虫之JS逆向实例-1>新浪网_第7张图片

图7 定位到加密函数扣出代码本地生成

base64 = {
    encode: function(n) {
        n = "" + n;
        if (n == "") {
            return ""
        }
        var l = "";
        var u, s, q = "";
        var t, r, p, o = "";
        var m = 0;
        do {
            u = n.charCodeAt(m++);
            s = n.charCodeAt(m++);
            q = n.charCodeAt(m++);
            t = u >> 2;
            r = ((u & 3) << 4) | (s >> 4);
            p = ((s & 15) << 2) | (q >> 6);
            o = q & 63;
            if (isNaN(s)) {
                p = o = 64
            } else {
                if (isNaN(q)) {
                    o = 64
                }
            }
            l = l + this._keys.charAt(t) + this._keys.charAt(r) + this._keys.charAt(p) + this._keys.charAt(o);
            u = s = q = "";
            t = r = p = o = ""
        } while (m < n.length);
        return l
    } 
    },
    _keys: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    _keys_urlsafe: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",
    _subp_v2_keys: "uAL715W8e3jJCcNU0lT_FSXVgxpbEDdQ4vKaIOH2GBPtfzqsmYZo-wRM9i6hynrk=",
    _subp_v3_keys_3: "5WFh28sGziZTeS1lBxCK-HgPq9IdMUwknybo.LJrQD3uj_Va7pE0XfcNR4AOYvm6t"
};


console.log(base64.encode("113222222"))

<python爬虫之JS逆向实例-1>新浪网_第8张图片

<python爬虫之JS逆向实例-1>新浪网_第9张图片

图8 定位到加密位置寻找加密函数

<python爬虫之JS逆向实例-1>新浪网_第10张图片

图9 寻找到加密函数 本地生成

2.nonce  - 随机生成固定位数字符串

// len = 你想要生成多少位的随机组合结果----- 该加密写死了6位
var makeNonce = function(len) {
    var x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    var str = "";
    for (var i = 0; i < len; i++) {
        str += x.charAt(Math.ceil(Math.random() * 1000000) % x.length)
    }
    return str
};
console.log(makeNonce(6))

3.sp   -  对servertime时间戳 + nonce随机字符串 + 密码 进行加密

<python爬虫之JS逆向实例-1>新浪网_第11张图片

图10 跟踪到生成raskey

<python爬虫之JS逆向实例-1>新浪网_第12张图片

图11 生成key后与参数一起进行加密

在本地调试rsa加密时内部会有检查navigator中的appName、appVersion参数需要自己本地构造。


navigator = {
    appName: "Netscape",
    appVersion: "5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
  
}, window = this, window.navigator = navigator;

sinaSSOEncoder = {
    "base64": {
        "_keys": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
        "_keys_urlsafe": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",
        "_subp_v2_keys": "uAL715W8e3jJCcNU0lT_FSXVgxpbEDdQ4vKaIOH2GBPtfzqsmYZo-wRM9i6hynrk=",
        "_subp_v3_keys_3": "5WFh28sGziZTeS1lBxCK-HgPq9IdMUwknybo.LJrQD3uj_Va7pE0XfcNR4AOYvm6t"
    },
    "Cookie": {},
    "getSUBPCookie": {},
    "n": null,
    "e": 0,
    "d": null,
    "p": null,
    "q": null,
    "dmp1": null,
    "dmq1": null,
    "coeff": null
}

!(function() {
        var av;
        var ah = 244837814094590;
        var Y = ((ah & 16777215) == 15715070);
        function aq(z, t, az) {
            if (z != null) {
                if ("number" == typeof z) {
                    this.fromNumber(z, t, az)
                } else {
                    if (t == null && "string" != typeof z) {
                        this.fromString(z, 256)
                    } else {
  
        function S() {
            d(new Date().getTime())
        }
        if (T == null) {
            T = new Array();
            ab = 0;
            var I;
            if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto && typeof (window.crypto.random) === "function") {
                var F = window.crypto.random(32);
                for (I = 0; I < F.length; ++I) {
                    T[ab++] = F.charCodeAt(I) & 255
                }
            }
            while (ab < M) {
                I = Math.floor(65536 * Math.random());
                T[ab++] = I >>> 8;
                T[ab++] = I & 255
            }
            ab = 0;
            S()
        }
   
        function L() {
            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(z, t) {
            if (z != null && t != null && z.length > 0 && t.length > 0) {
                this.n = g(z, 16);
                this.e = parseInt(t, 16)
            } else {
                alert("Invalid RSA public key")
            }
        }
        function V(t) {
            return t.modPowInt(this.e, this.n)
        }
        function p(az) {
            var t = ae(az, (this.n.bitLength() + 7) >> 3);
            if (t == null) {
                return null
            }
            var aA = this.doPublic(t);
            if (aA == null) {
                return null
            }
            var z = aA.toString(16);
            if ((z.length & 1) == 0) {
                return z
            } else {
                return "0" + z
            }
        }
        L.prototype.doPublic = V;
        L.prototype.setPublic = o;
        L.prototype.encrypt = p;
        this.RSAKey = L
    }

).call(sinaSSOEncoder);

最终输出结果:

<python爬虫之JS逆向实例-1>新浪网_第13张图片

你可能感兴趣的:(web逆向,python,爬虫)