首页 > 其他分享 >(四)JS逆向——中国观鸟网

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

时间:2024-07-05 14:30:30浏览次数:15  
标签:function 逆向 return url JS import var 观鸟网 data

爬取观鸟网的信息

 有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
     }
}

 

标签:function,逆向,return,url,JS,import,var,观鸟网,data
From: https://www.cnblogs.com/sxy-blog/p/18285762

相关文章

  • threejs入门2:Creating a scene
    参考:https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-sceneThegoalofthissectionistogiveabriefintroductiontothree.js.Wewillstartbysettingupascene,withaspinningcube.Aworkingexampleisprovidedatthebottomof......
  • windows安装以及切换使用nodejs多版本
    1安装nvmnvm是一个简单的bash脚本,它是用来管理系统中多个已存的Node.js版本。可以先把系统已有的node卸载掉,也可不卸载,但是以防没必要的冲突,尽量还是卸掉。1.1下载nvm下载地址:https://github.com/coreybutler/nvm-windows/releases,下载.zip后缀的这个文件,下载后解压安装即可......
  • JavaWeb—jsp篇
    概述JavaServerPages:java服务器端页面      可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码      用于简化书写 原理jsp实际就是一个servletjsp就是java代码  脚本<% 代码%>:定义的java代码,在service方法中。......
  • 邮件显示统计图表echarts-java+phantomjs实现
    邮件显示统计图表echarts-java+phantomjs实现项目背景是产品业务上的订阅推送,纯java后端实现,通过邮件将统计报表发送给用户。这里会涉及一些关键点:首先是统计图表的生成,我们采用常见的echarts,简单易用,支持图表类型丰富美观;java后端实现可使用echarts-java来实现图表的生成......
  • 数据集转换JSON
    procedureTForm1.DataSetToJSON(DataSet:TDataSet);varJSONObject:TJSONObject;JSONArray:TJSONArray;JSONItem:TJSONObject;i:integer;beginJSONArray:=TJSONArray.Create;//创建JSON数组//创建后不需要释放free(会自动释放),如果操作释放free动作会报错whilenot......
  • [NodeJS] timers阶段的源码解析
    timers阶段是Nodejs事件循环中的一个阶段,这一阶段主要是检查是否有到期的定时器,如果有则执行其回调。相关源码位置:timers阶段:node/deps/uv/src/timer.catmain·nodejs/node(github.com)timers阶段的代码比较少,这里直接贴出来,你也可以点进去上面的源码看自己感兴趣的部分......
  • Java 中Json中既有对象又有数组的参数 如何转化成对象
    1.示例一:解析一个既包含对象又包含数组的JSON字符串,并将其转换为Java对象在Java中处理JSON数据,尤其是当JSON结构中既包含对象又包含数组时,常用的库有org.json、Gson和Jackson。这里我将以Gson为例来展示如何解析一个既包含对象又包含数组的JSON字符串,并将其转换为Java对象。首先......
  • Qt Json详细介绍
    一.概念介绍JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,常用于前后端数据传输和存储。它具有以下特点:易读性:JSON使用人类可读的文本格式表示数据,采用键值对的方式组织数据,易于阅读和编辑。轻量级:JSON数据格式较为简洁,不包含冗余信息,适合网络传输和存......
  • Java中的JSON神器,如何轻松玩转复杂数据结构
    哈喽,大家好,我是木头左!一、揭秘JSON世界的基石在Java的世界中,JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,它基于文本,易于阅读和编写,同时也易于机器解析和生成。JSON在日常开发中的应用非常广泛,无论是前后端的数据交互,还是配置文件的读取,都离不开JSON的身影。那......
  • js实现视频截图
    截图原理:文件上传,将视频绘制到canvas中进行截图贴代码工具函数->base64转成文件exportconstdataURLtoFile=({dataURL="",filename=""}:{dataURL:stringfilename:string})=>{constarr=dataURL.split(",")constmime=arr[0]......