Reverse-建筑

摘要

本文内容转自网络,个人学习记录使用,请勿传播

建筑市场监管平台数据采集

需求

网址:http://jzsc.mohurd.gov.cn/data/company

爬取某一个省份企业数据,基于搜索实现指定某一个具体的省份

分析

  • 进行省份的条件设置,点击查询按钮后,捕获到的数据包中存储的是加密的响应数据,因此需要对其进行解密,获取明文数据,该明文数据就是制定省份的企业数据。

  • 问题:如何查找加密解密的js操作?

    • 加密数据是通过ajax请求获取的,回忆ajax请求代码:

      • 1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        $.ajax({
        type : "POST", //提交方式
        url : "xxx?checkPersonnel",//请求的url
        data : {"str" : strData},//数据,这里使用的是Json格式进行传输
        success : function(data) {//返回数据根据结果进行相应的处理
        xxx //对请求到的数据data进行的相关操作
        }, error: function (e) {
        console.log(e);//请求失败执行的操作
        }
        });
    • 那么,在该网站一定会存在发起ajax请求的代码,且在ajax代码中一定会出现ajax请求的url,因此全局搜索,ajax请求的url后半部分(query/comp/list):

      • 在app数据包中定位到关键字

      • 1
        2
        3
        4
        5
        6
        a["a"].request({
        url: "/dataservice/query/comp/list",
        params: t,
        method: "get"
        })
        }
      • 没有发现任何函数,则单步执行(120次大概)

        • 1
          2
          3
          4
          5
          t.interceptors.response.use(function(t) {
          var e = JSON.parse(h(t.data));//h(t.data)解密t.data加密数据
          return 408 == e.code && o["a"].commit("SET_CaptchaDilaog", !0),
          e
          },
        • 进入到函数h内部查看:

          • 1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            , s = n("4328")
            , l = n.n(s)
            , u = n("3452")
            , d = n.n(u)
            , p = n("5c96")
            , f = d.a.enc.Utf8.parse("jo8j9wGw%6HbxfFn")//将key转为二进制
            , m = d.a.enc.Utf8.parse("0123456789ABCDEF");//将iv转为二进制
            function h(t) {
            var e = d.a.enc.Hex.parse(t)
            , n = d.a.enc.Base64.stringify(e)
            , a = d.a.AES.decrypt(n, f, { //n是密文数据,f是key,f的值在上面代码定义
            iv: m, //m是iv,m的值也在上面代码定义
            mode: d.a.mode.CBC,
            padding: d.a.pad.Pkcs7
            })
            , r = a.toString(d.a.enc.Utf8);
            return r.toString() //断点位置
        • 分析上述代码:

          • AES加密,提取key和iv

          • python改写:

          • 1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            from Crypto.Cipher import AES
            import json
            response = '密文数据'
            f = 'jo8j9wGw%6HbxfFn' # 秘钥
            m = '0123456789ABCDEF' # 偏移值
            # 转码为字节类型
            m = bytes(m, encoding='utf-8')
            f = bytes(f, encoding='utf-8')
            # 创建一个AES算法 秘钥 模式 偏移值
            cipher = AES.new(f, AES.MODE_CBC, m)
            # 解密
            decrypt_content = cipher.decrypt(bytes.fromhex(response))
            result = str(decrypt_content, encoding='utf-8')
            print(result)