• 13-爬虫之js加密,解密,混淆,逆向破解思路


    url:https://www.aqistudy.cn/apinew/aqistudyapi.php

    分析思路:

    原图
    原图
    现图
    在这里插入图片描述

    1,我们点击查询按钮后发现抓取到了2个一样的数据包,包含请求url和post的请求方式

    在这里插入图片描述

    2,发起多次请求发现 请求参数 d 是动态加密的数据值,我们只要能破解其中一个数据包的内容剩下的一个也可以同理破解

    在这里插入图片描述
    在这里插入图片描述

    3,返回的响应数据就是我们想要捕获的空气指标数据值,我们发现响应数据也是一组被加密的密文数据,我们必须将密文数据解密成原文数据才可以被我们使用

    在这里插入图片描述

    4,通过类型可以看见发起的是ajax请求

    在这里插入图片描述

    分析的结论

    请求url
    Request URL: https://www.aqistudy.cn/apinew/aqistudyapi.php 
    请求方式 
    Request Method: POST 
    动态变化的参数
    d: tdgHOYxwKdDSgYXe+RLPzYCgLvrddahasI5XXklB4gVLYqab+XRPpMD/oSqnJ/aEmFwzVEUhLnPzRy03+X1BIzLvxQKwu4A3YsqR3OemYgNnHqPdBwvJlbxia99YeK+xVtm/KUfxgICnZHiin/ojfqe1ZJXPHKDaOqwKab2iJt6YQRF4WQWYusdfEXhDolRtLCUy8ht8s821u5VxPcU+NezPIcU8U830QPCeWGAkKrHcsmuUaEHoRLJjnqpMnaid8OfacV5HCUeVhK3Uhju9Sr+bGsXveRwJFs5t307AlxFmwOBzCa6T6fmAQK9+1KoOfUz8EtNUEQkMB1LQBarJd9qsFKpe6TnoLFJ9G6xud+YIs8GecqTX4Pf2urDJLQ3LLfmLqMo7H/7LwYcq2BxyJiGqG2Xpp5wdr9L+oCZisZ9yKEBuYIprEM6A9PMUKADaw5ZESt11e9YX/xbkKPbnaw== 
    返回的加密的响应数据
    f9VXvMyFOzW7AzFWZjMa3oW5basBySGVYXbOpPoS6/W7Dh2wAk4bbiAr7xpyn/meJ/Hem3nHWnk4WtHFwrhKIyDSu2SUsVB5a/jusoqnpmDCxqr9YxCavi6qiilWtiVa49+C70wNGkoQqdo5w3hB/g==
    
    

    破解操作

    请求得到的数据是一组加密数据,但是web前台展示的是一组明文数据,原因是前台将响应回来的密文数据进行了解密
    注:在该网站的相关数据包中是存在这解密方法,我们只需要将其解密方法获取,就可对密文数据进行解密

    找寻ajax请求的代码
    获取搜索按钮对应的点击事件绑定的函数即可(使用火狐浏览器找寻点击事件的函数代码)

    在这里插入图片描述

    点击搜索按钮对应的点击事件函数名叫做getData,进入该函数内部扎寻ajax请求代码

    在这里插入图片描述

    找到了getDate函数的实现
    • 没有发现ajax代码的实现

    • 发现函数内部调用了另外的两个函数getAQIData();
      getWeatherData();

    • 那么ajax代码的实现一定是在上诉两个函数内部

    • 有价值的信息: type==“HOUR” 查询时间是以小时为单位

    • 进入getAQIData();getWeatherData();函数内部找寻ajax代码实现

      • 在这两个函数内部没有发现ajax代码的实现
      • 发现他两都调用了一个名叫getServerData()的函数,那么ajax代码一定存在getServerData()函数中
        在这里插入图片描述
        在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    进入getServerData函数内部找寻ajax代码
    • 通过搜索我们发现只有2个getServerData的调用并不是函数的定义,那么getServerData并不在 city_datail.html中
      在这里插入图片描述

    在这里插入图片描述

    • 函数实现的找寻,需要在抓包工具中进行全局搜索
    • 找到的结果是密文
    js 混淆
    	- 在网站后台,关键的重要的js函数的实现为了保密,一般会对这些js函数代码进行混淆(加密),所以我们需要对js混淆的代码进行反混淆,将js加密的函数进行解密
    

    在这里插入图片描述

    js反混淆

    js混淆暴力破解https://www.bm8.com.cn/jsConfusion/
    在这里插入图片描述
    在这里插入图片描述

    function getServerData(method, object, callback, period) {
            const key = hex_md5(method + JSON.stringify(object));
            const data = getDataFromLocalStorage(key, period);
            if (!data) {
                var param = getParam(method, object);
                $.ajax({
                    url: '../apinew/aqistudyapi.php', #请求url
                    data: {
                        d: param #加密且动态变化的请求参数
                    },
                    type: "post",#请求方式
                    #data请求到的加密的响应数据
                    success: function (data) {
                        data = decodeData(data);#将data这个加密的响应数据进行解密
                        obj = JSON.parse(data);
                        if (obj.success) {
                            if (period > 0) {
                                obj.result.time = new Date().getTime();
                                localStorageUtil.save(key, obj.result)
                            }
                            callback(obj.result)
                        } else {
                            console.log(obj.errcode, obj.errmsg)
                        }
                    }
                })
            } else {
                callback(data)
            }
        }
    
    分析getServerData函数实现的ajax代码:

    - 动态变化且加密的请求参数

    js逆向

    我们需要借助于 PyExecJS 库来实现模拟JavaScript代码执行获取动态加密的请求参数,然后再将加密的响应数据带入decodeData进行解密即可!

    • PyExecJS介绍:PyExecJS 是一个可以使用 Python 来模拟运行 JavaScript 的库。我们需要pip install PyExecJS对其进行环境安装。
    • 以及安装nodejs的开发环境:https://jingyan.baidu.com/article/e4511cf38c05092b845eaf9b.html
      - 开始执行js:
      • 1.创建一个jsCode.js文件将反混淆网站中的代码粘贴进去

    在这里插入图片描述

    在这里插入图片描述
    - 2.在jsCode.js文件中添加一个自定义函数getPostParamCode,该函数是为了获取且返回post请求的动态加密参数:

    function getPostParamCode(method, city, type, startTime, endTime){
        var param = {};
        param.city = city;
        param.type = type;
        param.startTime = startTime;
        param.endTime = endTime;
        return getParam(method, param);
    }
    

    在这里插入图片描述
    - 在py源文件中可以基于PyExecJS模拟执行jsCode.js中定义好的自定义函数,获取动态加密参数:

    import execjs
    import requests
    
    
    url = "https://www.aqistudy.cn/apinew/aqistudyapi.php"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
    }
    
    #实例化一个对象
    node = execjs.get()
    # Params
    method = 'GETCITYWEATHER'
    city = '北京'
    type = 'HOUR'
    start_time = '2020-08-27 00:00:00'
    end_time = '2020-08-28 23:00:00'
    
    # Compile javascript
    file = 'jsCode.js' #代加载编译的js源文件
    ctx = node.compile(open(file, encoding='utf-8').read())#加载编译的js源文件中的js代码
    # Get params
    js = 'getPostParamCode("{0}", "{1}", "{2}", "{3}", "{4}")'.format(method, city, type, start_time, end_time)
    params = ctx.eval(js)# eval表示执行指定js函数
    print(params)#返回的是加密变化的请求参数
    

    在这里插入图片描述

    • 我们用 requests 库来模拟 POST 请求
    import execjs
    import requests
    
    
    url = "https://www.aqistudy.cn/apinew/aqistudyapi.php"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
    }
    
    #实例化一个对象
    node = execjs.get()
    # Params
    method = 'GETCITYWEATHER'
    city = '北京'
    type = 'HOUR'
    start_time = '2020-08-27 00:00:00'
    end_time = '2020-08-28 23:00:00'
    
    # Compile javascript
    file = 'jsCode.js' #代加载编译的js源文件
    ctx = node.compile(open(file, encoding='utf-8').read())#加载编译的js源文件中的js代码
    # Get params
    js = 'getPostParamCode("{0}", "{1}", "{2}", "{3}", "{4}")'.format(method, city, type, start_time, end_time)
    params = ctx.eval(js)# eval表示执行指定js函数
    print(params)
    
    data = {
        "d":params
    }
    page_text = requests.post(url=url,headers=headers,data=data).text
    print(page_text)# 返回的是加密的响应数据
    

    在这里插入图片描述

    • 接下来我们再调用一下 JavaScript 中的 decodeData() 方法即可实现解密
    完整代码
    import execjs
    import requests
    
    
    url = "https://www.aqistudy.cn/apinew/aqistudyapi.php"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
    }
    
    #实例化一个对象
    node = execjs.get()
    # Params
    method = 'GETCITYWEATHER'
    city = '北京'
    type = 'HOUR'
    start_time = '2020-08-27 00:00:00'
    end_time = '2020-08-28 23:00:00'
    
    # Compile javascript
    file = 'jsCode.js' #代加载编译的js源文件
    ctx = node.compile(open(file, encoding='utf-8').read())#加载编译的js源文件中的js代码
    # Get params
    js = 'getPostParamCode("{0}", "{1}", "{2}", "{3}", "{4}")'.format(method, city, type, start_time, end_time)
    params = ctx.eval(js)# eval表示执行指定js函数
    print(params)
    
    data = {
        "d":params
    }
    page_text = requests.post(url=url,headers=headers,data=data).text
    print(page_text)# 返回的是加密的响应数据
    
    # 对加密的响应数据进行解密
    js = 'decodeData("{0}")'.format(page_text)
    decrypted_data = ctx.eval(js)
    print(decrypted_data) #解密后的真实数据
    
    
    

    完美结束

  • 相关阅读:
    Windows XP中万能断点
    c#运算符 ?
    转神秘的程序员
    经典解决“线程间操作无效
    文件上传
    dowload.aspx
    mail
    js 正则
    新年快乐
    DataTable Compute
  • 原文地址:https://www.cnblogs.com/gemoumou/p/13635332.html
Copyright © 2020-2023  润新知