(四)JS逆向——中国观鸟网

爬取观鸟网的信息

 有sign值,timestamp和requestid,要看这些值是怎么生成的

 载荷有加密的数据

 返回值也经过加密

 搜索requestid,找到了eval加密的代码,通过解密,就能找到生成这些值的代码段

 代码格式化后,找到了这几个值的生成位置

 requestid的生成是随机值,timestamp是时间戳

 e是一些限制条件,通过url编码可知,pointname是地点名称,所以e就是一些限制条件,然后序列化成了字符串

sign值就是这个值的字符串拼接,再通过md5加密

 JSEncrypt是一个第三方库,通过npm install jsencrypt

encryptUnicodeLong函数是自定义的方法修改的源代码,所以找到这个函数的位置

 

这就是自定义的函数,使其支持中文加密,复制到本地的源码内,就可以获取data值

 

python代码

import json
import requests
from functools import partial
import time
import hashlib
import subprocess
subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")
import execjs
from urllib.parse import urlencode
from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import pad,unpad


url = "https://api.birdreport.cn/front/record/activity/search"

e = {
    "limit":"20",
    "page":"4",
    "pointname":"梧桐沟"
}

# url编码
e = urlencode(e)

# 读取并执行js代码
with open("bird.js", 'r') as f:
    jscode = f.read()
js = execjs.compile(jscode)
res = js.call("jiami",e)

# 获取请求头和data
headers = res.get('header')
data = res.get("data")

# 补充请求头
headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
    "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",
    "Referer":"https://www.birdreport.cn/",
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
})

res = requests.post(url=url, data=data, headers=headers)
data = res.json().get("data")

# base64解码
data = base64.b64decode(data)

# aes解密
key = "3583ec0257e2f4c8195eec7410ff1619"
iv = "d93c0d5ec6352f20"
aes = AES.new(key.encode('utf-8'), AES.MODE_CBC,iv.encode())
ret = aes.decrypt(data)
print(ret.decode())

js代码

var JSEncrypt = require('node-jsencrypt');
// 引入md5标准库
const CryptoJS = require('crypto-js');

function MD5(password) {
  const encryptedPassword = CryptoJS.MD5(password).toString();
  return encryptedPassword;
}

function getUuid() {
    var s = [];
    var a = "0123456789abcdef";
    for (var i = 0; i < 32; i++) {
        s[i] = a.substr(Math.floor(Math.random() * 0x10), 1)
    }
    s[14] = "4";
    s[19] = a.substr((s[19] & 0x3) | 0x8, 1);
    s[8] = s[13] = s[18] = s[23];
    var b = s.join("");
    return b
}

function sort_ASCII(a) {
    var b = new Array();
    var c = 0;
    for (var i in a) {
        b[c] = i;
        c++
    }
    var d = b.sort();
    var e = {};
    for (var i in d) {
        e[d[i]] = a[d[i]]
    }
    return e
}

function url2json(a) {
    var b = /^[^\?]+\?([\w\W]+)$/, reg_para = /([^&=]+)=([\w\W]*?)(&|$|#)/g, arr_url = b.exec(a), ret = {};
    if (arr_url && arr_url[1]) {
        var c = arr_url[1], result;
        while ((result = reg_para.exec(c)) != null) {
            ret[result[1]] = result[2]
        }
    }
    return ret
}

function dataTojson(a) {
    var b = [];
    var c = {};
    b = a.split('&');
    for (var i = 0; i < b.length; i++) {
        if (b[i].indexOf('=') != -1) {
            var d = b[i].split('=');
            if (d.length == 2) {
                c[d[0]] = d[1]
            } else {
                c[d[0]] = ""
            }
        } else {
            c[b[i]] = ''
        }
    }
    return c
}

const serialize = function (a) {
    var b = [];
    for (var p in a) if (a.hasOwnProperty(p) && a[p]) {
        b.push(encodeURIComponent(p) + '=' + encodeURIComponent(a[p]))
    }
    return b.join('&')
};
var paramPublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvxXa98E1uWXnBzXkS2yHUfnBM6n3PCwLdfIox03T91joBvjtoDqiQ5x3tTOfpHs3LtiqMMEafls6b0YWtgB1dse1W5m+FpeusVkCOkQxB4SZDH6tuerIknnmB/Hsq5wgEkIvO5Pff9biig6AyoAkdWpSek/1/B7zYIepYY0lxKQIDAQAB";
var encrypt = new JSEncrypt();
encrypt.setPublicKey(paramPublicKey);

 function jiami(text) {
    var c = Date.parse(new Date());
    var d = getUuid();
    var e = JSON.stringify(sort_ASCII(dataTojson(text || '{}')));
    data = encrypt.encryptUnicodeLong(e);
    var f = MD5(e + d + c);
    // 返回需要的数据
     return {
        header:{
            timestamp:c.toString(),
            requestId:d,
            sign:f
        },
         data:data
     }
}

 

posted @ 2024-07-05 14:26  Mrterrific  阅读(110)  评论(0编辑  收藏  举报