zoukankan      html  css  js  c++  java
  • 对 js加密数据进行爬取和解密

    对 js加密数据进行爬取和解密

    • 分析:
      • 爬取的数据是动态加载
      • 并且我们进行了抓包工具的全局搜索,没有查找到结果
        • 意味着:爬取的数据从服务端请求到的是加密的密文数据
      • 页面每10s刷新一次,刷新后发现数据更新,但是浏览器地址栏的url没有变,说明加载出的数据是由ajax请求到的。
        • 动态加载出来的数据是由ajax请求到的,并且请求到的数据为加密数据
      • 定位到ajax数据包,从中可以看到url和动态变化的请求参数和加密的相应数据
      • 将ajax请求到的密文数据捕获
        • 动态的获取动态变化的请求参数
        • 基于抓包工具进行了动态变化请求参数taken的全局搜索,定位到了taken产生的源头,就是如下js代码:
          • var token = md5(String(page) + String(num) + String(timestamp));
      • 对密文数据进行解密
        • 通过分析找到了解密的js函数:decode_str(encode_str),encode_str就是密文数据
      • 查找encode_str的实现:
        • js逆向:将js代码转换成python代码。开发环境只能执行python代码
    • 首先将js代码中的ASCII码进行转换:
    function decode_str(scHZjLUh1) {
        #Base64.decode(scHZjLUh1)
        scHZjLUh1 = Base64["x64x65x63x6fx64x65"](scHZjLUh1);
        key = 'x6ex79x6cx6fx6ex65x72';#key = 'b'nyloner'
        len = key["x6cx65x6ex67x74x68"];
        code = '';
        for (i = 0; i < scHZjLUh1["x6cx65x6ex67x74x68"]; i++) {
            var coeFYlqUm2 = i % len;
            code += window["x53x74x72x69x6ex67"]["x66x72x6fx6dx43x68x61x72x43x6fx64x65"](scHZjLUh1["x63x68x61x72x43x6fx64x65x41x74"](i) ^ key["x63x68x61x72x43x6fx64x65x41x74"](coeFYlqUm2))
        }
        return Base64["x64x65x63x6fx64x65"](code)
    }
    
    
    'x64x65x63x6fx64x65'.encode('utf-8')
    
    b'decode'
    
    function decode_str(scHZjLUh1) {
        #Base64.decode(scHZjLUh1)
        scHZjLUh1 = Base64.decode(scHZjLUh1);
        key = 'nyloner';
        len = key.length;
        code = '';
        for (i = 0; i < scHZjLUh1.length; i++) {
            var coeFYlqUm2 = i % len;
            code += window.String.fromCharCode(scHZjLUh1.charCodeAt(i) ^ key.charCodeAt(coeFYlqUm2))
        }
        return Base64.decode(code)
    }
    
    • 代码实现:
    import time
    import hashlib
    import requests
    import base64
    

    将js代码装换成python代码:

    #js逆向之后的结果
    def decode_str(scHZjLUh1):
        #解密成字符串
        scHZjLUh1 = base64.decodestring(scHZjLUh1.encode())
        key = 'nyloner'
        lenth = len(key)
        code = ''
        sch_lenth = len(scHZjLUh1)
        for i in range(sch_lenth):
            coeFYlqUm2 = i % lenth
            #chr(0-255)返回对应编码的字符
            #ord(a-z)返回编码数值
            code += chr(scHZjLUh1[i] ^ ord(key[coeFYlqUm2]))
        code = base64.decodestring(code.encode())
        code = code.decode('utf-8')
        return code
    
    def getToken():
        page = str(1)
        num = str(15)
        t = str(int(time.time()))
        md5 = hashlib.md5()
        md5.update((page+num+t).encode('utf-8'))
        token = md5.hexdigest()
        return token
    
    token = getToken()
    url = 'https://nyloner.cn/proxy'
    param = {
        'num':'15',
        'page':'1',
        't':str(int(time.time())),
        'token':token
        
    }
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
        'Cookie':'sessionid=20ryihg87smnkko2kx6634jbcf4umhfp'
    }
    
    # 获取的是一个json串
    code = requests.get(url,headers=headers,params=param).json().get('list')
    str_code = decode_str(code)
    str_code
    

    下面是js代码中的获取数据和调用解密函数的部分代码:

    function get_proxy_ip(page, num, click_btn) {
        var timestamp = Date.parse(new Date());
        timestamp = timestamp / 1000;
        var token = md5(String(page) + String(num) + String(timestamp));
        $.get('../proxy?page=' + page + '&num=' + num + '&token=' + token + '&t=' + timestamp, function (result) {
            if (result.status === 'true') {
                var setHtml = "";
                $("#ip-list").html(setHtml);
                var encode_str = result.list;
                var items = str_to_json(decode_str(encode_str));
                for (var index = 0; index < items.length; ++index) {
                    item = items[index];
                    setHtml += "<tr>
    <td>" + (index + 1) + "</td>
    ";
                    setHtml += "<td>" + item.ip.toString() + "</td>
    ";
                    setHtml += "<td>" + item.port.toString() + "</td>
    ";
                    setHtml += "<td>" + item.time.toString() + "</td>
    </tr>
    ";
                }
                $("#ip-list").html(setHtml);
                if (click_btn === 'next') {
                    document.getElementById("last-page").disabled = false;
                    if (items.length < 15) {
                        document.getElementById("next-page").disabled = true;
                    }
                } else {
                    document.getElementById("next-page").disabled = false;
                    if (page === 1) {
                        document.getElementById("last-page").disabled = true;
                    }
                }
    
            }
        });
    }
    
  • 相关阅读:
    在实体属性上通过注解格式化日期
    @Validated和@Valid区别:Spring validation验证框架对入参实体进行嵌套验证必须在相应属性(字段)加上@Valid而不是@Validated
    两种根据关键字查询的方法SQL
    excel批量导入数据
    下载excel模板
    上传人员照片
    身份证校验类
    把字符串参数分割成数组 传入SQL foreach遍历查询
    使用Hibernate-Validator优雅的校验参数
    如何使用Graphics2D在一张图片上画线(包括箭头)
  • 原文地址:https://www.cnblogs.com/zhufanyu/p/11996937.html
Copyright © 2011-2022 走看看