安卓 逆向高级-人均瑞数

news2024/11/24 14:00:56

引言:

JS 爬虫,绕不过瑞数这道坎,卡的死死的。一般网上的教程就是补环境什么的,我尝试了,可以但是比较麻烦。 今天说一种,秒过的方式,抗并发。那就是牛逼的RPC,hook JS 技术。

前期准备:

  1. 安装nodejs

下载地址:

Node.js — Run JavaScript Everywhere

安装依赖

npm install ws

npm  install express

  1. Google浏览器

F12 调试,会反反调试

  1. 代码1,NodeJS 端

完成1,组装http服务,提供对外接口,方便其他地方直接调用. 2 ,监控websocket 服务,与hook 的js 交互,http服务连接websocket,websocket 连接hookjs, js 直接调用网站的协议。

代码:

global.navigator = {appName: 'nodejs'}; // fake the navigator object

global.window = {}; // fake the window object

const express=require('express');

const server=express();

const bodyParser = require('body-parser');

server.listen(8093,'0.0.0.0',function(){

    console.log('http://localhost:8093');

});

server.use(bodyParser.urlencoded({ extended: false })); //调用中间件

server.use(bodyParser.json())

 //import * as WebSocket from 'ws';

const WebSocket = require('ws')

const server1 = new WebSocket.Server({ port: 8013 });

console.log('begin')

server1.on('connection', (socket) => {

  console.log('New client connected');

  socket.on('message', (message) => {

    console.log(`Received message: ${message}`);

try {

    // 向所有客户端广播消息

    if(message.indexOf("ping") >=0 ) {

        server1.clients.forEach((client) => {

        if (client.readyState === WebSocket.OPEN) {

            client.send("ping");

        }

        });

    }else if(message.indexOf("rep") >=0 ) {

       // global.retmsg = message;

       str = ` ${message}`

       var args = str.split('|');

       uuid = args[2]

       var tmpjs = JSON.parse(args[1])

       global.resps[uuid].json({code:1,message:'',data:tmpjs,uuid:uuid})

       global.resps[uuid] = null;

       // global.resp.json({code:1,message:'',data:str})

    }

}catch(error) {

console.log(error);

}

  });

  socket.on('close', () => {

    console.log('Client disconnected');

  });

});

global.resps = {}

function guid() {

    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {

        var r = Math.random() * 16 | 0,

            v = c == 'x' ? r : (r & 0x3 | 0x8);

        return v.toString(16);

    });

}

global.server = server1

server.post('/list',function(req,resp){

    console.log("list 接收参数:" + req.body + new Date());

    //global.resp = undefined;

   // uuid = guid();

   uuid = req.body.uuid;

    server1.clients.forEach((client) => {

        if (client.readyState === WebSocket.OPEN) {

            global.retmsg = "";

            client.send("list|"+JSON.stringify(req.body) +"|" + uuid);

        }

        });       

        global.resps[uuid] =  resp

    }

 );

const WebSocket = require('ws')

const server1 = new WebSocket.Server({ port: 8013 });

监听 websocket 端口 8013

这个是心跳包,网页js 与 nodejs 保持连接,保持心跳用

  // 向所有客户端广播消息

    if(message.indexOf("ping") >=0 ) {

        server1.clients.forEach((client) => {

        if (client.readyState === WebSocket.OPEN) {

            client.send("ping");

        }

        });

    }

// 这个是定义的websocket 返回,接收到websocket 返回,然后发送给 http 客户端。

}else if(message.indexOf("rep") >=0 ) {

       // global.retmsg = message;

       str = ` ${message}`

       var args = str.split('|');

       uuid = args[2]

       var tmpjs = JSON.parse(args[1])

       global.resps[uuid].json({code:1,message:'',data:tmpjs,uuid:uuid})

       global.resps[uuid] = null;

       // global.resp.json({code:1,message:'',data:str})

    }

// 这里定义一个对外http 服务,list就是 http://localhost:8093/list , 参数json格式

{ “data”:”11”,”uuid”:”333”}, 有一个全局变量   global.resps, 他这样存储   global.resps[uuid] =  resp 一个uuid 即一个http客户端的变量,方便从websocke他得到返回之后,直接给他发送消息。

  client.send("list|"+JSON.stringify(req.body) +"|" + uuid); ,这个是http 收到数据,直接发送给websocket 即js 客户端就行。

server.post('/list',function(req,resp){

    console.log("list 接收参数:" + req.body + new Date());

   uuid = req.body.uuid;

    server1.clients.forEach((client) => {

        if (client.readyState === WebSocket.OPEN) {

            global.retmsg = "";

            client.send("list|"+JSON.stringify(req.body) +"|" + uuid);

        }

        });       

        global.resps[uuid] =  resp

    }

 );

  1. 代码2, js hook 端
  1. 1 先来看下一个实例网站。

启动器,定位到请求位置所在。

//跟踪进去代码,是直接发送ajax,那一分钟就搞定。瑞数就是说他会hook ajax send 函数,添加头,添加cookie 之类的。我们搞不顶瑞数,但是可以写ajax 请求啊

2.2 js 端代码:

function patch_ruishu(url){

    console.log("RPC args:"+url);

    var v = [];

    v.push(window.hc_url(url));

    v.push(window.hc_cook(945, 10,false));

    return v;

}

// 闭包

!function (a) {

    // Promise是一种用于处理异步操作的机制

    // 该函数接受两个参数:resolve和reject。

    // resolve是一个函数,用于将Promise从挂起状态转换为已解决状态(fulfilled),并返回解决结果(通常是异步操作的结果)。

    // reject是一个函数,用于将Promise从挂起状态转换为已拒绝状态(rejected),并返回拒绝原因(通常是异步操作的错误信息)。

    new Promise((e, s) => {

            e(a)

        }

    ).then((myFunction) => {

            var cbb_MyId = "1001";

            // 执行下面语句之后,客户端就会与服务器进行连接。

            ws = new WebSocket("ws://127.0.0.1:8013");

            // 指定连接成功后的回调函数

            ws.onopen = function () {

                console.log("服务器连接成功!");

                // send 向服务器发送数据

             

                

               

                setInterval(function () {

                    ws.send(cbb_MyId+'ping---'+"connect");

                }, 5000)

                

            }

            ;

            window.ws = ws;

            // 收到服务器数据后的回调函数。

            ws.onmessage = function (evt) {

                if (evt.data.indexOf("ping") >= 0) {

                    console.log('ping')

                    return;

                }

                console.log('传入数据: ' + evt.data);

                if(evt.data.indexOf("list") >=0 ) {

                    //调用方法

                    var args = evt.data.split('|');

                    console.log(args[1]);

                    var reqdata = JSON.parse(args[1]);

                   try {

                    var serviceNbr = reqdata.mobile;

                    var param ="userInfo.loginType=4&userInfo.serviceNbr="+serviceNbr+"&flag=0&chargeType=undefined"

                    

                    var code = mycode(serviceNbr.replace(/ /g,""),"7");

                    param=param+"&key="+code;

                    $.ajax({

                        type:'POST',

                        url:"https://ah.189.cn/service/pay/findByUser.action",

                        data:param,

                        dataType:'json',

                        cache:false,

                        //async:false,

                        success:function (data) {

                       

                            if(data.flag == '0'){

                                ws.send("rep|"+ JSON.stringify(data)+ "|" + args[2])

                            }else {

                                ws.send("rep|"+ JSON.stringify(data)+ "|" + args[2])

                            }

                        }

                        });

                    }catch(e) {

                        console.log(e)

                    }

                   

$.ajax({

                    type: "POST",

                    contentType: "application/x-www-form-urlencoded;charset=utf-8",

                    url: path + "/service/index/getDistrictBargain.action",

                    dataType: "json",

                    success: function(data) {

                        var listDistrictBargain = data.listDistrictBargain;

                        var page = data.page;

                        ws.send("rep|"+ JSON.stringify(page)+ "|" + args[2])

                    },

                    error: function() {

                    }

                });

                }

            };

            // 连接关闭后的回调函数

            ws.onclose = function () {

                console.log("rpc已经断开了哦");

            };

            // 连接错误后的回调函数

            ws.onerror = function () {

                console.log("rpc已经断开了哦");

            };

        }

    )

    ;

}(patch_ruishu)  // 这里填返回加密数据的js函数名字

初始化websocket ,然后连上刚才的nodejs

   ws = new WebSocket("ws://127.0.0.1:8013");

            // 指定连接成功后的回调函数

            ws.onopen = function () {

                console.log("服务器连接成功!");

                // send 向服务器发送数据

             

                

               

                setInterval(function () {

                    ws.send(cbb_MyId+'ping---'+"connect");

                }, 5000)

                

            }

            ;

  1. 收到请求:

   if(evt.data.indexOf("list") >=0 ) {

                    //调用方法

                    var args = evt.data.split('|');

                    console.log(args[1]);

                    var reqdata = JSON.parse(args[1]);

                   try {

                    var serviceNbr = reqdata.mobile;

                    var param ="userInfo.loginType=4&userInfo.serviceNbr="+serviceNbr+"&flag=0&chargeType=undefined"

                    

                    var code = mycode(serviceNbr.replace(/ /g,""),"7");

                    param=param+"&key="+code;

                    $.ajax({

                        type:'POST',

                        url:"https://ah.189.cn/service/pay/findByUser.action",

                        data:param,

                        dataType:'json',

                        cache:false,

                        //async:false,

                        success:function (data) {

                       

                            if(data.flag == '0'){

                                ws.send("rep|"+ JSON.stringify(data)+ "|" + args[2])

                            }else {

                                ws.send("rep|"+ JSON.stringify(data)+ "|" + args[2])

                            }

                        }

                        });

                    }catch(e) {

                        console.log(e)

                    }

                   

$.ajax({

                    type: "POST",

                    contentType: "application/x-www-form-urlencoded;charset=utf-8",

                    url: path + "/service/index/getDistrictBargain.action",

                    dataType: "json",

                    success: function(data) {

                        var listDistrictBargain = data.listDistrictBargain;

                        var page = data.page;

                        ws.send("rep|"+ JSON.stringify(page)+ "|" + args[2])

                    },

                    error: function() {

                    }

                });

                }

  1. Node js 远程
  2. C# 远程。
  3. Js websocket 注意事项 如何hook, 如何页面reload ,如何替换js

高级防止 掉线问题,Ip 问题 ,浏览器指纹问题 抗并发,抗造。 如何生产部署,快速集成到csharpcef  框架

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1689912.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RedisTemplateAPI:List

文章目录 ⛄介绍⛄List的常见命令有⛄RedisTemplate API❄️❄️添加缓存❄️❄️将List放入缓存❄️❄️设置过期时间(单独设置)❄️❄️获取List缓存全部内容(起始索引,结束索引)❄️❄️从左或从右弹出一个元素❄️❄️根据索引查询元素❄…

【日记】跟奇安信斗智斗勇,败下阵来(416 字)

正文 今天一个客户都没有,让我快怀疑我们银行是不是要倒闭了…… 因为内外网 u 盘不知所踪,所以重新制了一个。深刻体会到了奇安信有多烂。有两个 u 盘,奇安信似乎把主控写坏了,插上电脑有反应,但是看不见盘符&#xf…

游戏陪玩/在线租号/任务系统网站源码

源码介绍 游戏陪玩系统/在线租号系统/小姐姐陪玩任务系统/网游主播任务威客平台源码/绝地吃鸡LOL在线下单/带手机端/声优线上游戏任务系统网站源码 界面美观,功能齐全,已对接支付,安装教程放源码压缩包里了! 界面截图 源码下载 https://download.csdn.net/download/huayula…

【Fiddler抓包工具】第四节.断点设置和弱网测试

文章目录 前言一、断点设置 1.1 全局断点 1.2 局部断点 1.3 打断点的几种常用命令 1.4 篡改响应报文二、弱网测试 2.1 网络限速 2.2 精准限速总结 前言 一、断点设置 1.1 全局断点 特点: 中断Fiddler捕获的所有请求,包括…

系统架构师考试(九)

TCP/IP协议族 SMTP是简单邮件传输协议 DNS 域名解析协议 URL - IP,通过URL解析ip是哪一台电脑 DHCP 动态IP地址分配的协议 SNMP 简单网络管理协议 TFTP 简单文件管理协议 ICMP 是网络中差错校验,差错报错的协议 IGMP G是组,组…

cuda11.2安装哪个版本的tensorflow-gpu

在官网上找到这个表格,因为自己的电脑一直配置的11.2的cuda,所以也不想换,最好就是安装一般能适应该版本的tensorflow,我配置了python3.8的环境,然后进行 pip install tensorflow-gpu2.6 回车就会自动从清华镜像上进…

基于vue3速学angular

因为工作原因,需要接手新的项目,新的项目是angular框架的,自学下和vue3的区别,写篇博客记录下: 参考:https://zhuanlan.zhihu.com/p/546843290?utm_id0 1.结构上: vue3:一个vue文件&#xff…

金职优学:分析央国企面试如何通关?

在当今竞争激烈的就业市场中,中央和国有企业(以下简称“央国企”)的面试机会对求职者来说是非常有吸引力的。这些企业通常拥有稳定的发展前景、良好的薪酬福利和广阔的职业发展空间。但是,要想成功通过央国企的面试,求…

力扣HOT100 - 31. 下一个排列

解题思路: 数字是逐步增大的 步骤如下: class Solution {public void nextPermutation(int[] nums) {int i nums.length - 2;while (i > 0 && nums[i] > nums[i 1]) i--;if (i > 0) {int j nums.length - 1;while (j > 0 &&…

2024年二建准考证打印入口已开通!

24年二建将于6月1日、2日举行,目前西藏、陕西准考证打印入口已开通,各省也将陆续开始准考证打印工作。 2024二建考试时间安排 2024二建准考证打印时间 二建准考证打印须知 01 准考证打印信息显示空白怎么办? 1)使用电脑自带的浏览器重新试一下。 2)…

【全开源】填表统计预约打卡表单系统FastAdmin+ThinkPHP+UniApp

简化流程,提升效率 一、引言:传统表单处理的局限性 在日常工作和生活中,我们经常会遇到需要填写表单、统计数据和预约打卡等场景。然而,传统的处理方式往往效率低下、易出错,且不利于数据的统计和分析。为了解决这些…

Spring Web MVC介绍及详细教程

目录 1.什么是Spring Web MVC? 1.1 MVC定义 1.2 Spring MVC与MVC关系 2.为什么要学习Spring MVC 3.项目创建 4.Spring MVC连接 4.1 RequestMapping 4.2 PostMapping和GetMapping 5.Spring MVC参数获取 5.1 获取单个参数 5.2 获取多个参数 5.3 获取普通对…

Web3 游戏平台 Creo Engine 销毁代币总量的20%,以促进长远发展

Creo Engine 5月16日进行了第三次代币销毁,这次的销毁占代币总量的 20%。一共销毁了2亿 $CERO 代币,市场价值接近 2000 万美元。 Creo Engine 致力于连接世界、为玩家提供一站式游戏中心,并提升 Web3 游戏体验。 Creo Engine 发布于2022年&am…

springboot集成达梦数据库8,用springboot+mtbatisplus查询值为空

springboot集成达梦数据库8,用springbootmtbatisplus查询值为空 背景:springboot集成达梦数据库8,用springbootmtbatisplus查询值为空,但是在DB管理工具中是可以查询到数据的。 原因及解决方法:执行添加语句后&#xf…

iclone acculips Visemes (Adding Visemes to Dictionary)

(New for v7.9) 将视位添加到词典(v7.9 的新增功能) AccuLips has a dictionary behind the scenes to map and convert voice to text. Needless to say, some existing English lexicon can still be missing from the dictionary, and cause the cor…

java BioJava库安装和使用

BioJava是一个用Java编写的开源生物信息学库,旨在为生物学家和生物信息学家提供工具和算法来处理生物数据。它提供了一系列功能强大的工具,包括读取、写入和解析常见的生物信息学文件格式(如FASTA、GenBank等),进行序列…

视频码流分析工具

一、VQ Analyzer 在线使用说明: https://vicuesoft.com/vq-analyzer/userguide/ ref: Video Analyzer and Streaming Tester Software – VQ Analyzer HEVC 分析工具 - 懒人李冰 推荐一个开源且跨平台的免费码流分析软件YUView - 知乎

PMapper:助你在AWS中实现IAM权限快速安全评估

关于PMapper PMapper是一款功能强大的脚本工具,该工具本质上是一个基于Python开发的脚本/代码库,可以帮助广大研究人员识别一个AWS账号或AWS组织中存在安全风险的IAM配置,并对IAM权限执行快速评估。 PMapper可以将目标AWS帐户中的不同IAM用户…

【Android】Gradle插件全局配置/Gradle插件下载源配置

gradle插件概念 gradle发行包和gradle插件是两个东西,可以理解为maven版本与maven依赖项的关系。gradle插件由项目路径中的build.gradle文件进行管理,相当于pom.xmlsettings.xml,同时记录依赖项和依赖仓库。是一个依赖项,从指定仓…

云原生|为什么服务网格能够轻松重塑微服务?一文讲清楚!

目录 一、概述 二、 设计 三、服务网格 四、总结 一、概述 容器化技术与容器编排推动了微服务架构应用的演进,于是应用的扩展与微服务的数量日益增加,新的问题随之而来,监控服务的性能变得越来越困难,微服务与微服务之间相互通…