首页
苏兮影视
随笔记
壁纸
更多
直播
时光轴
友联
关于
统计
Search
1
软件添加id功能按钮
708 阅读
2
v2ray节点搭建
508 阅读
3
typecho非常有特色的模块
460 阅读
4
QQxml消息卡片生成源码
421 阅读
5
Linux下提权常用小命令
366 阅读
谈天说地
建站源码
经验教程
资源分享
动漫美图
登录
Search
标签搜索
java
flutter
springboot
rust
安卓
linux
vue
docker
joe
快捷键
git
fish shell
maven
redis
netty
dart
groovy
js
设计模式
rpc
尽意
累计撰写
95
篇文章
累计收到
38
条评论
首页
栏目
谈天说地
建站源码
经验教程
资源分享
动漫美图
页面
苏兮影视
随笔记
壁纸
直播
时光轴
友联
关于
统计
搜索到
1
篇与
的结果
2024-08-13
js逆向xhs(二)
分享另一种思路,要明确我们最终的目的都是要拿到加密函数的返回值,这期间做的任何准备都是为了加密值做服务的,所以可以使用websocket作为通信,间接调用加密函数,拿到加密值使用netty作为ws服务器public class WebSocketServer { public static final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); public static void main(String[] args) throws Exception { NioEventLoopGroup bossGroup = new NioEventLoopGroup(); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ChannelPipeline p = ch.pipeline(); p.addLast(new HttpServerCodec()); p.addLast(new HttpObjectAggregator(65536)); p.addLast(new HttpContentCompressor()); p.addLast(new WebSocketServerProtocolHandler("/")); p.addLast(new WebSocketFrameHandler()); } }); System.out.println("server run ..."); ChannelFuture future = bootstrap.bind(8080).sync(); future.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } static class WebSocketFrameHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); System.out.println(ctx.channel().remoteAddress()+":connect"); channelGroup.add(ctx.channel()); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); channelGroup.remove(ctx.channel()); System.out.println(ctx.channel().remoteAddress()+":disconnect"); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if (msg instanceof WebSocketFrame) { WebSocketFrame frame = (WebSocketFrame) msg; if (frame instanceof TextWebSocketFrame) { if (channelGroup.size()<2) return; channelGroup.stream().filter(ch->ch != ctx.channel()).forEach(ch->ch.writeAndFlush(frame)); } } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { System.out.println(ctx.channel().remoteAddress()+"连接出错:"+cause.getMessage()); ctx.close(); } } }在浏览器环境运行jsxhs这里由于用到了window全局变量储存加密函数,所以我们只要在控制台或者代码段地方执行我们直接的代码逻辑,因为是在xhs的网站作用域下,是可以直接使用全局变量的const singletonFunction = (function() { let instance; let executed = false; function createInstance() { if (!executed) { var sgin = window._webmsxyw; const ws = new WebSocket('ws://127.0.0.1:8080/'); ws.onopen = function(evt){ ws.send("我已连接,状态良好"); console.log("我已连接,状态良好"); } ws.onmessage = function(evt){ var data = JSON.parse(evt.data); console.log(data,data.c,data.i); ws.send(JSON.stringify(sgin(data.c,data.i))); } executed = true; } } return function() { if (!instance) { instance = createInstance; } return instance; }; })(); singletonFunction()();这里注入的方案有很多,也可以使用代理添加我们自己的逻辑,或者编写油猴脚本也是可以的。说一下手动注入吧,原理都大差不差点开全部选项,选择替换点击选择放置替换的文件夹选择文件夹后允许,勾选上本地替换依旧是找到加密函数的位置,通过搜索匹配右键该文件,选择替换内容将我们的代码添加到指定位置即可现在保存再刷新网页,就会走我们本地的js代码启动服务端先用websocket在线测试网站查看运行情况https://www.wetools.com/websocket是能成功拿到加密后的数据的接下来就是在项目中拿到这里加密的内容了使用okhttp连接ws服务器def client = new OkHttpClient() def request = new Request.Builder().url("ws://localhost:8080").build() client.newWebSocket(request,new WebSocketListener() { @Override void onMessage(@NotNull WebSocket webSocket, @NotNull String text) { super.onMessage(webSocket, text) println text } })现在加密值也拿到了,带上加密值正常请求接口即可
2024年08月13日
51 阅读
0 评论
3 点赞