rpc某银理财 payload加密

本教程仅供学习交流,不得用于任何商业用途!!!
任何非法商业使用及商业利益冲突带来的法律纠纷,与此无关,概不负责!!!

前言

一些网站,由于js逆向的成本太高而请求量不大,这个时候选择jsrpc 可以剩下不少时间

目录

前言

1、下载适配自己操作系统的版本以及源码

2、将源码解压 然后把下载的版本放到源码根目录下

3、源码的一个目录结构

4、rpc实现原理

5、打开编译好的文件(我的是windows 所有打开的是window_amd64.exe) 这一步就是就是创建服务端

6、api的介绍

7、注入JS,构建通信环境(JsRpc/resouces/JsEnv_Dev.js at main · jxhczhl/JsRpc)创建客户端

8、服务端 客户端 建立连接 在客户端控制台输入下面任意一条代码

9、远程调用方法介绍

一、接口传js代码让浏览器执行

(一) 客户端和服务端以及建立连接后 调用execjs接口就行

二、浏览器预先注册js方法 传递函数名调用

(一) 无参数获取值

(二) 带参数获取值

(三) 带多个参数 并且使用post方式取值

(四) 获取页面基础信息

10、项目实操

(一) 首先找到目标网址它的载荷是加密的

(二) 其次找到加密函数,使它暴露在全局变量中,这里我是通过替换文件直接修改代码将其暴露

(三) 选择合适的方式获取值


目标网站某银理财

jsrpc工具网址:GitHub - jxhczhl/JsRpc: 远程调用(rpc)浏览器方法,免去抠代码补环境 (需要科学上网)

1、下载适配自己操作系统的版本以及源码

2、将源码解压 然后把下载的版本放到源码根目录下

3、源码的一个目录结构

main.go (服务器的主代码)
resouces/JsEnv_De.js (客户端注入js环境)
config.yaml (可选配置文件)

4、rpc实现原理

在网站的控制台新建一个WebScoket客户端链接到服务器通信,调用服务器的接口 服务器会发送信息给客户端 客户端接收到要执行的方法执行完js代码后把获得想要的内容发回给服务器 服务器接收到后再显示出来

5、打开编译好的文件(我的是windows 所有打开的是window_amd64.exe) 这一步就是就是创建服务端

6、api的介绍

  • /list :查看当前连接的ws服务 (get)
  • /ws :浏览器注入ws连接的接口 (ws | wss)
  • /wst :ws测试使用-发啥回啥 (ws | wss)
  • /go :获取数据的接口 (get | post)
  • /execjs :传递jscode给浏览器执行 (get | post)
  • /page/cookie :直接获取当前页面的cookie (get)
  • /page/html :获取当前页面的html (get)

说明:接口用?group分组 如 "ws://127.0.0.1:12080/ws?group={}" 以及可选参数 clientId clientId说明:以group分组后,如果有注册相同group的 可以传入这个id来区分客户端,如果不传 服务程序会自动生成一个。当访问调用接口时,服务程序随机发送请求到相同group的客户端里。

//注入例子 group可以随便起名(必填) http://127.0.0.1:12080/go?group={}&action={}&param={} //这是调用的接口 group填写上面注入时候的,action是注册的方法名,param是可选的参数 param可以传string类型或者object类型(会尝试用JSON.parse)

7、注入JS,构建通信环境(JsRpc/resouces/JsEnv_Dev.js at main · jxhczhl/JsRpc)创建客户端

function Hlclient(wsURL) {
    this.wsURL = wsURL;
    this.handlers = {
        _execjs: function (resolve, param) {
            var res = eval(param)
            if (!res) {
                resolve("没有返回值")
            } else {
                resolve(res)
            }

        }
    };
    this.socket = undefined;
    if (!wsURL) {
        throw new Error('wsURL can not be empty!!')
    }
    this.connect()
}

Hlclient.prototype.connect = function () {
    console.log('begin of connect to wsURL: ' + this.wsURL);
    var _this = this;
    try {
        this.socket = new WebSocket(this.wsURL);
        this.socket.onmessage = function (e) {
            _this.handlerRequest(e.data)
        }
    } catch (e) {
        console.log("connection failed,reconnect after 10s");
        setTimeout(function () {
            _this.connect()
        }, 10000)
    }
    this.socket.onclose = function () {
        console.log('rpc已关闭');
        setTimeout(function () {
            _this.connect()
        }, 10000)
    }
    this.socket.addEventListener('open', (event) => {
        console.log("rpc连接成功");
    });
    this.socket.addEventListener('error', (event) => {
        console.error('rpc连接出错,请检查是否打开服务端:', event.error);
    });

};
Hlclient.prototype.send = function (msg) {
    this.socket.send(msg)
}

Hlclient.prototype.regAction = function (func_name, func) {
    if (typeof func_name !== 'string') {
        throw new Error("an func_name must be string");
    }
    if (typeof func !== 'function') {
        throw new Error("must be function");
    }
    console.log("register func_name: " + func_name);
    this.handlers[func_name] = func;
    return true

}

//收到消息后这里处理,
Hlclient.prototype.handlerRequest = function (requestJson) {
    var _this = this;
    try {
        var result = JSON.parse(requestJson)
    } catch (error) {
        console.log("catch error", requestJson);
        result = transjson(requestJson)
    }
    //console.log(result)
    if (!result['action']) {
        this.sendResult('', 'need request param {action}');
        return
    }
    var action = result["action"]
    var theHandler = this.handlers[action];
    if (!theHandler) {
        this.sendResult(action, 'action not found');
        return
    }
    try {
        if (!result["param"]) {
            theHandler(function (response) {
                _this.sendResult(action, response);
            })
            return
        }
        var param = result["param"]
        try {
            param = JSON.parse(param)
        } catch (e) {}
        theHandler(function (response) {
            _this.sendResult(action, response);
        }, param)

    } catch (e) {
        console.log("error: " + e);
        _this.sendResult(action, e);
    }
}

Hlclient.prototype.sendResult = function (action, e) {
    if (typeof e === 'object' && e !== null) {
        try {
            e = JSON.stringify(e)
        } catch (v) {
            console.log(v)//不是json无需操作
        }
    }
    this.send(action + atob("aGxeX14") + e);
}

function transjson(formdata) {
    var regex = /"action":(?<actionName>.*?),/g
    var actionName = regex.exec(formdata).groups.actionName
    stringfystring = formdata.match(/{..data..:.*..\w+..:\s...*?..}/g).pop()
    stringfystring = stringfystring.replace(/\\"/g, '"')
    paramstring = JSON.parse(stringfystring)
    tens = `{"action":` + actionName + `,"param":{}}`
    tjson = JSON.parse(tens)
    tjson.param = paramstring
    return tjson
}

8、服务端 客户端 建立连接 在客户端控制台输入下面任意一条代码

// 注入环境后连接通信
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zzz");
// 可选  
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zzz&clientId=hliang/"+new Date().getTime())

执行完成后,通过查看服务端会发现有一个新上线的连接,此时已经连接成功了

9、远程调用方法介绍

一、接口传js代码让浏览器执行

(一) 客户端和服务端以及建立连接后 调用execjs接口就行
import requests

js_code = """
(function(){
    console.log("test")
    return "执行成功"
})()
"""

url = "http://localhost:12080/execjs"
data = {
    "group": "zzz",
    "code": js_code
}
res = requests.post(url, data=data)
print(res.text)

二、浏览器预先注册js方法 传递函数名调用

(一) 无参数获取值

// 注册一个方法 第一个参数hello为方法名,
// 第二个参数为函数,resolve里面的值是想要的值(发送到服务器的)
demo.regAction("hello", function (resolve) {
    //这样每次调用就会返回“好困啊+随机整数”
    var Js_sjz = "好困啊"+parseInt(Math.random()*1000);
    resolve(Js_sjz);
})

访问接口,获得js端的返回值
http://127.0.0.1:12080/go?group=zzz&action=hello

(二) 带参数获取值
//写一个传入字符串,返回base64值的接口(调用内置函数btoa)
demo.regAction("hello2", function (resolve,param) {
    //这样添加了一个param参数,http接口带上它,这里就能获得
    var base666 = btoa(param)
    resolve(base666);
})

访问接口,获得js端的返回值

http://127.0.0.1:12080/go?group=zzz&action=hello2&param=123456

(三) 带多个参数 并且使用post方式取值
//假设有一个函数 需要传递两个参数
function hlg(User,Status){
    return User+"说:"+Status;
}

demo.regAction("hello3", function (resolve,param) {
    //这里还是param参数 param里面的key 是先这里写,但到时候传接口就必须对应的上
    res=hlg(param["user"],param["status"])
    resolve(res);
})

访问接口,获得js端的返回值

url = "http://127.0.0.1:12080/go"
data = {
    "group": "zzz",
    "action": "hello3",
    "param": json.dumps({"user":"黑脸怪","status":"好困啊"})
}
print(data["param"]) #dumps后就是长这样的字符串{"user": "\u9ed1\u8138\u602a", "status": "\u597d\u56f0\u554a"}
res=requests.post(url, data=data) #这里换get也是可以的
print(res.text)
(四) 获取页面基础信息
resp = requests.get("http://127.0.0.1:12080/page/html?group=zzz")     # 直接获取当前页面的html
resp = requests.get("http://127.0.0.1:12080/page/cookie?group=zzz")   # 直接获取当前页面的cookie

10、项目实操

(一) 首先找到目标网址它的载荷是加密的

(二) 其次找到加密函数,使它暴露在全局变量中,这里我是通过替换文件直接修改代码将其暴露

通过测试已经暴露成功了

(三) 选择合适的方式获取值

这里加密函数只需要接收一个参数,可以选择带参获取值,这里定义一个名为data_encode的函数

demo.regAction("data_encode", function (resolve,param) {
    //这样添加了一个param参数,http接口带上它,这里就能获得
    resolve(window.SmAencrypt(param));
})

然后到浏览器(客户端)注册这个函数,true表示注册成功

然后编写python代码去访问,结果显示可以正常拿到加密数据真nice

import requests

data = '{"order":"desc","currCode":"","current":2,"finType":"P","keyWord":"","orderBy":"ipoBgnDt","pageSize":5,"prodClcMode":"01","prodLimit":[],"saCode":"","saleState":"","userId":0}'

url = f"http://127.0.0.1:12080/go?group=zzz&action=data_encode&param={data}"

res = requests.get(url)
print(res.text)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值