js逆向xhs(二)

尽意
2024-08-13 / 0 评论 / 51 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年08月13日,已超过162天没有更新,若内容或图片失效,请留言反馈。
分享另一种思路,要明确我们最终的目的都是要拿到加密函数的返回值,这期间做的任何准备都是为了加密值做服务的,所以可以使用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();
        }
    }
}

在浏览器环境运行js

xhs这里由于用到了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()();

这里注入的方案有很多,也可以使用代理添加我们自己的逻辑,或者编写油猴脚本也是可以的。

说一下手动注入吧,原理都大差不差
点开全部选项,选择替换
lzs6y5rb.png
点击选择放置替换的文件夹
lzs6ze6f.png
选择文件夹后允许,勾选上本地替换
lzs70g41.png

依旧是找到加密函数的位置,通过搜索匹配
lzs71tql.png

右键该文件,选择替换内容
lzs72tto.png

将我们的代码添加到指定位置即可
lzs74leq.png

现在保存再刷新网页,就会走我们本地的js代码

启动服务端

先用websocket在线测试网站查看运行情况
https://www.wetools.com/websocket

lzs6riek.png

lzs6rteo.png

是能成功拿到加密后的数据的

接下来就是在项目中拿到这里加密的内容了

使用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
    }
})

现在加密值也拿到了,带上加密值正常请求接口即可

3

评论 (0)

取消