某侠网js逆向wasm解析

本次目标地址如下,使用base64解密获得
aHR0cHM6Ly93d3cud2FpbWFveGlhLm5ldC9sb2dpbg==

打开网址,本次的目标是登录接口,如下图
在这里插入图片描述
本文主要讲解wasm的解析,所以对其他参数不做逆向处理,本次由wasm加密的参数只有sign一个,我们跟栈查看源代码
在这里插入图片描述
从这里发现,sign由sign函数通过传入其他5个参数获得,我们查看sign函数
在这里插入图片描述
sign函数是go这个类中的一个函数,其中go中用到的_inst.exports.resume函数是wasm中的加密函数,如下图展示:
在这里插入图片描述
这就是本文需要解析的wasm文件,接着,我们寻找wasm文件的导入操作部分,全局搜索wasm,发现这个位置有通过fetch请求得到wasm文件
在这里插入图片描述
我们还原这段加载wasm的代码,并补齐then调用需要用到的Go这个类,js如下

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// This file has been modified for use by the TinyGo compiler.// End of polyfills for common API.const encoder = new TextEncoder("utf-8");const decoder = new TextDecoder("utf-8");var logLine = [];global.Go = class {constructor() {this._callbackTimeouts = new Map();this._nextCallbackTimeoutID = 1;const mem = () => {// The buffer may change when requesting more memory.return new DataView(this._inst.exports.memory.buffer);}const setInt64 = (addr, v) => {mem().setUint32(addr + 0, v, true);mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);}const getInt64 = (addr) => {const low = mem().getUint32(addr + 0, true);const high = mem().getInt32(addr + 4, true);return low + high * 4294967296;}const loadValue = (addr) => {const f = mem().getFloat64(addr, true);if (f === 0) {return undefined;}if (!isNaN(f)) {return f;}const id = mem().getUint32(addr, true);return this._values[id];}const storeValue = (addr, v) => {const nanHead = 0x7FF80000;if (typeof v === "number") {if (isNaN(v)) {mem().setUint32(addr + 4, nanHead, true);mem().setUint32(addr, 0, true);return;}if (v === 0) {mem().setUint32(addr + 4, nanHead, true);mem().setUint32(addr, 1, true);return;}mem().setFloat64(addr, v, true);return;}switch (v) {case undefined:mem().setFloat64(addr, 0, true);return;case null:mem().setUint32(addr + 4, nanHead, true);mem().setUint32(addr, 2, true);return;case true:mem().setUint32(addr + 4, nanHead, true);mem().setUint32(addr, 3, true);return;case false:mem().setUint32(addr + 4, nanHead, true);mem().setUint32(addr, 4, true);return;}let id = this._ids.get(v);if (id === undefined) {id = this._idPool.pop();if (id === undefined) {id = this._values.length;}this._values[id] = v;this._goRefCounts[id] = 0;this._ids.set(v, id);}this._goRefCounts[id]++;let typeFlag = 1;switch (typeof v) {case "string":typeFlag = 2;break;case "symbol":typeFlag = 3;break;case "function":typeFlag = 4;break;}mem().setUint32(addr + 4, nanHead | typeFlag, true);mem().setUint32(addr, id, true);}const loadSlice = (array, len, cap) => {return new Uint8Array(this._inst.exports.memory.buffer, array, len);}const loadSliceOfValues = (array, len, cap) => {const a = new Array(len);for (let i = 0; i < len; i++) {a[i] = loadValue(array + i * 8);}return a;}const loadString = (ptr, len) => {return decoder.decode(new DataView(this._inst.exports.memory.buffer, ptr, len));}const timeOrigin = Date.now() - performance.now();this.importObject = {wasi_snapshot_preview1: {// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_writefd_write: function(fd, iovs_ptr, iovs_len, nwritten_ptr) {let nwritten = 0;if (fd == 1) {for (let iovs_i=0; iovs_i<iovs_len;iovs_i++) {let iov_ptr = iovs_ptr+iovs_i*8; // assuming wasm32let ptr = mem().getUint32(iov_ptr + 0, true);let len = mem().getUint32(iov_ptr + 4, true);nwritten += len;for (let i=0; i<len; i++) {let c = mem().getUint8(ptr+i);if (c == 13) { // CR// ignore} else if (c == 10) { // LF// write linelet line = decoder.decode(new Uint8Array(logLine));logLine = [];console.log(line);} else {logLine.push(c);}}}} else {console.error('invalid file descriptor:', fd);}mem().setUint32(nwritten_ptr, nwritten, true);return 0;},fd_close: () => 0,      // dummyfd_fdstat_get: () => 0, // dummyfd_seek: () => 0,       // dummy"proc_exit": (code) => {if (global.process) {// Node.jsprocess.exit(code);} else {// Can't exit in a browser.throw 'trying to exit with code ' + code;}},random_get: (bufPtr, bufLen) => {crypto.getRandomValues(loadSlice(bufPtr, bufLen));return 0;},},env: {// func ticks() float64"runtime.ticks": () => {return timeOrigin + performance.now();},// func sleepTicks(timeout float64)"runtime.sleepTicks": (timeout) => {// Do not sleep, only reactivate scheduler after the given timeout.setTimeout(this._inst.exports.go_scheduler, timeout);},// func finalizeRef(v ref)"syscall/js.finalizeRef": (sp) => {// Note: TinyGo does not support finalizers so this should never be// called.//console.error('syscall/js.finalizeRef not implemented');const id = mem().getUint32(sp + 8, true);this._goRefCounts[id]--;if (this._goRefCounts[id] === 0) {const v = this._values[id];this._values[id] = null;this._ids.delete(v);this._idPool.push(id);}},// func stringVal(value string) ref"syscall/js.stringVal": (ret_ptr, value_ptr, value_len) => {const s = loadString(value_ptr, value_len);storeValue(ret_ptr, s);},// func valueGet(v ref, p string) ref"syscall/js.valueGet": (retval, v_addr, p_ptr, p_len) => {let prop = loadString(p_ptr, p_len);let value = loadValue(v_addr);let result = Reflect.get(value, prop);storeValue(retval, result);},// func valueSet(v ref, p string, x ref)"syscall/js.valueSet": (v_addr, p_ptr, p_len, x_addr) => {const v = loadValue(v_addr);const p = loadString(p_ptr, p_len);const x = loadValue(x_addr);Reflect.set(v, p, x);},// func valueDelete(v ref, p string)"syscall/js.valueDelete": (v_addr, p_ptr, p_len) => {const v = loadValue(v_addr);const p = loadString(p_ptr, p_len);Reflect.deleteProperty(v, p);},// func valueIndex(v ref, i int) ref"syscall/js.valueIndex": (ret_addr, v_addr, i) => {storeValue(ret_addr, Reflect.get(loadValue(v_addr), i));},// valueSetIndex(v ref, i int, x ref)"syscall/js.valueSetIndex": (v_addr, i, x_addr) => {Reflect.set(loadValue(v_addr), i, loadValue(x_addr));},// func valueCall(v ref, m string, args []ref) (ref, bool)"syscall/js.valueCall": (ret_addr, v_addr, m_ptr, m_len, args_ptr, args_len, args_cap) => {const v = loadValue(v_addr);const name = loadString(m_ptr, m_len);const args = loadSliceOfValues(args_ptr, args_len, args_cap);try {const m = Reflect.get(v, name);storeValue(ret_addr, Reflect.apply(m, v, args));mem().setUint8(ret_addr + 8, 1);} catch (err) {storeValue(ret_addr, err);mem().setUint8(ret_addr + 8, 0);}},// func valueInvoke(v ref, args []ref) (ref, bool)"syscall/js.valueInvoke": (ret_addr, v_addr, args_ptr, args_len, args_cap) => {try {const v = loadValue(v_addr);const args = loadSliceOfValues(args_ptr, args_len, args_cap);storeValue(ret_addr, Reflect.apply(v, undefined, args));mem().setUint8(ret_addr + 8, 1);} catch (err) {storeValue(ret_addr, err);mem().setUint8(ret_addr + 8, 0);}},// func valueNew(v ref, args []ref) (ref, bool)"syscall/js.valueNew": (ret_addr, v_addr, args_ptr, args_len, args_cap) => {const v = loadValue(v_addr);const args = loadSliceOfValues(args_ptr, args_len, args_cap);try {storeValue(ret_addr, Reflect.construct(v, args));mem().setUint8(ret_addr + 8, 1);} catch (err) {storeValue(ret_addr, err);mem().setUint8(ret_addr+ 8, 0);}},// func valueLength(v ref) int"syscall/js.valueLength": (v_addr) => {return loadValue(v_addr).length;},// valuePrepareString(v ref) (ref, int)"syscall/js.valuePrepareString": (ret_addr, v_addr) => {const s = String(loadValue(v_addr));const str = encoder.encode(s);storeValue(ret_addr, str);setInt64(ret_addr + 8, str.length);},// valueLoadString(v ref, b []byte)"syscall/js.valueLoadString": (v_addr, slice_ptr, slice_len, slice_cap) => {const str = loadValue(v_addr);loadSlice(slice_ptr, slice_len, slice_cap).set(str);},// func valueInstanceOf(v ref, t ref) bool"syscall/js.valueInstanceOf": (v_addr, t_addr) => {return loadValue(v_addr) instanceof loadValue(t_addr);},// func copyBytesToGo(dst []byte, src ref) (int, bool)"syscall/js.copyBytesToGo": (ret_addr, dest_addr, dest_len, dest_cap, source_addr) => {let num_bytes_copied_addr = ret_addr;let returned_status_addr = ret_addr + 4; // Address of returned boolean status variableconst dst = loadSlice(dest_addr, dest_len);const src = loadValue(source_addr);if (!(src instanceof Uint8Array)) {mem().setUint8(returned_status_addr, 0); // Return "not ok" statusreturn;}const toCopy = src.subarray(0, dst.length);dst.set(toCopy);setInt64(num_bytes_copied_addr, toCopy.length);mem().setUint8(returned_status_addr, 1); // Return "ok" status},// copyBytesToJS(dst ref, src []byte) (int, bool)// Originally copied from upstream Go project, then modified://   https://github.com/golang/go/blob/3f995c3f3b43033013013e6c7ccc93a9b1411ca9/misc/wasm/wasm_exec.js#L404-L416"syscall/js.copyBytesToJS": (ret_addr, dest_addr, source_addr, source_len, source_cap) => {let num_bytes_copied_addr = ret_addr;let returned_status_addr = ret_addr + 4; // Address of returned boolean status variableconst dst = loadValue(dest_addr);const src = loadSlice(source_addr, source_len);if (!(dst instanceof Uint8Array)) {mem().setUint8(returned_status_addr, 0); // Return "not ok" statusreturn;}const toCopy = src.subarray(0, dst.length);dst.set(toCopy);setInt64(num_bytes_copied_addr, toCopy.length);mem().setUint8(returned_status_addr, 1); // Return "ok" status},}};}async run(instance) {this._inst = instance;this._values = [ // JS values that Go currently has references to, indexed by reference idNaN,0,null,true,false,global,this,];this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference idthis._ids = new Map();  // mapping from JS values to reference idsthis._idPool = [];      // unused ids that have been garbage collectedthis.exited = false;    // whether the Go program has exitedconst mem = new DataView(this._inst.exports.memory.buffer)while (true) {const callbackPromise = new Promise((resolve) => {this._resolveCallbackPromise = () => {if (this.exited) {throw new Error("bad callback: Go program has already exited");}setTimeout(resolve, 0); // make sure it is asynchronous};});this._inst.exports._start();if (this.exited) {break;}await callbackPromise;}}_resume() {if (this.exited) {throw new Error("Go program has already exited");}this._inst.exports.resume();if (this.exited) {this._resolveExitPromise();}}_makeFuncWrapper(id) {const go = this;return function () {const event = { id: id, this: this, args: arguments };go._pendingEvent = event;go._resume();return event.result;};}}M = new GoG = "https://wmx-1253696238.cos.ap-shanghai.myqcloud.com/main.wasm";
WebAssembly.instantiateStreaming(fetch(G), M.importObject).then((function(t) {F = t.instance,M.run(F)console.log(sign("123", "79922afce16ebe8bce34bb651eb0494f", "000000cabf2f4f37bbb10c358b865c41","1X_RK3ag_IKlW15iHhSywQ==","2cc051e0c885a08dd046f1a789cffa72eddfc266f663cb2ded1ac08a5102bfe9", "1623828054"));}))

发现,直接调用即可,完美解决sign值
在这里插入图片描述

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

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

相关文章

DApp:去中心化的革命与挑战

DApp&#xff08;去中心化应用&#xff09;是一种基于区块链技术的应用程序&#xff0c;与传统的中心化应用程序不同&#xff0c;DApp具有去中心化、透明、不可篡改等特性。本文将介绍DApp的前世今生&#xff0c;以及它的优势和未来发展。 DApp的前世可以追溯到区块链技术的出现…

运维工具之tmux命令

tmux终端复用器的使用 1.tmux的概念 ​ tmux&#xff0c;“Terminal MultipleXer”,意思是"终端复用器"。是一个可以让人们通过一个窗口操作多个会话的工具&#xff0c;对于经常操作Linux系统的运维人员来说&#xff0c;绝对是一款提高工作效率的利器。 2.tmux能帮…

Kubernetes API 和流量控制:管理请求数量和排队进程

本文描述了我们最近遇到的一个真实案例&#xff1a;Kubernetes API 因其中一个集群中的大量请求而瘫痪。今天&#xff0c;我们将讨论我们如何处理这个问题&#xff0c;并提供一些关于如何预防它的提示。 高并发搞崩 Kubernetes API 一个非常普通的早晨&#xff0c;我们开始了…

SSC | Blue Prism报告:2024年智能自动化(IA)7大趋势预测

近日&#xff0c;RPA行业领导者SS&C | Blue Prism发布《2024智能自动化&#xff08;IA&#xff09;趋势与预测》报告。报告中提到&#xff0c;智能自动化&#xff08;IA&#xff09;与流程管理的有效融合&#xff0c;是实现数字化转型成功的核心。采用业务流程管理&#xf…

免费开源OCR 软件Umi-OCR

Umi-OCR 是一款免费、开源、可批量的离线 OCR 软件&#xff0c;基于 PaddleOCR&#xff0c;适用于 Windows10/11 平台 免费&#xff1a;本项目所有代码开源&#xff0c;完全免费。方便&#xff1a;解压即用&#xff0c;离线运行&#xff0c;无需网络。高效&#xff1a;自带高效…

数组的定义与越界问题

scanf标准读取函数 第一个冷知识&#xff0c;输入到scanf里面的内容都是字符串形式&#xff0c;但是&#xff01; scanf(“%d”,&a),%d决定了如何对输入的字符串进行操作 scanf用来读取标准输入&#xff0c;标准输入的内容需要放入到某个变量空间中去&#xff0c;因此变量…

Python数据分析案例34——IMDB电影评论情感分析(Transformer)

电影评论的情感分析 案例背景 很多同学对电影系列的数据都比较喜欢&#xff0c;那我就补充一下这个最经典的文本分类数据集&#xff0c;电影情感评论分析。用神经网络做。对国外的英文评论文本进行分类&#xff0c;看是正面还是负面情感。 数据集介绍 数据集&#xff1a;IMDb…

Python Tkinter Pack布局管理器

GUI 编程就相当于小孩子搭积木&#xff0c;每个积木块应该放在哪里&#xff0c;每个积木块显示为多大&#xff0c;也就是对大小和位置都需要进行管理&#xff0c;而布局管理器正是负责管理各组件的大小和位置的。此外&#xff0c;当用户调整了窗口的大小之后&#xff0c;布局管…

sphinx,一个神奇的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个神奇的 Python 库 - sphinx。 Github地址&#xff1a;https://github.com/sphinx-doc/sphinx/ 在软件开发和项目管理中&#xff0c;文档是不可或缺的一部分。好的文档可以…

企业工商年报在哪找?如何批量获取?

企业年报是什么&#xff1f;有什么用&#xff1f; 企业年报是企业每年必须向工商行政管理机关和税务机关报送的年度报告&#xff0c;是指公司整个会计年度的财务报告及其他相关文件。主要包括企业基本信息、资产负债表、利润表、现金流量表、股东及股本变化情况等内容。 作用…

SpringBoot集成p6spy

P6Spy 是一个可以用来在应用程序中拦截和修改数据操作语句的开源框架。 通过 P6Spy 我们可以对 SQL 语句进行拦截,相当于一个 SQL 语句的记录器,这样我们可以用它来作相关的分析,比如性能分析。这里主要用于在控制台打印SQL时能自动将问号替换成实际参数打印一个可执行的SQL…

SQL 语言详解

SQL 详解 我们通常可以将 SQL 分为四类&#xff0c;分别是 DDL&#xff08;数据定义语言&#xff09;、DML&#xff08;数据操作语言&#xff09;、DQL&#xff08;数据查询语言&#xff09;和 DCL&#xff08;数据控制语言&#xff09;。DDL 主要用于创建、删除、修改数据库中…

云计算任务调度仿真04

这次分享一篇更加高级的云计算任务调度的文章和代码&#xff0c; 基于A3C学习和残差回归神经网络的随机边缘云计算环境动态调度 网络结构 结果 代码示例 这是基于pytorch实现的&#xff0c;所以复现起来没有什么难度&#xff0c;但是可以看到这有六层网络&#xff0c;而且…

KubeSphere 核心实战之一【在kubesphere平台上部署mysql】(实操篇 1/3)

文章目录 1、登录kubesphere平台2、kubesphere部署应用分析2.1、工作负载2.2、服务2.3、应用路由2.4、任务2.5、存储与配置2.6、部署应用三要素 3、部署mysql3.1、mysql容器启动实例3.2、mysql部署分析3.3、创建mysql的配置3.4、创建mysql的数据卷pvc3.5、创建mysql工作负载3.6…

java应用中swagger使用

文章目录 前言使用依赖引入配置注解使用controller中注解实体类注解 页面展示 前言 现在前后端分离式开发&#xff0c;最头疼的部分就是接口文档了。最讨厌两种人&#xff0c;一种是不写接口文档的人&#xff0c;另一种则是让我写接口文档的人。实际上&#xff0c;我们有一款特…

yolov5_obb win10环境安装

1、项目地址&#xff1a; GitHub - hukaixuan19970627/yolov5_obb: yolov5 csl_label.(Oriented Object Detection)&#xff08;Rotation Detection&#xff09;&#xff08;Rotated BBox&#xff09;基于yolov5的旋转目标检测yolov5 csl_label.(Oriented Object Detection)…

手机与电脑更改IP地址怎么使用代理IP?

在现代互联网时代&#xff0c;代理IP已成为许多人日常生活和工作中不可或缺的一部分。通过代理IP&#xff0c;用户可以隐藏自己的真实IP地址&#xff0c;并获得更好的网络体验。本文将详细介绍如何在手机和电脑上更改IP地址并使用代理IP。 一、手机使用代理IP 1. 打开手机设置&…

微服务接口工具Swagger2

##1、什么是Swagger? # 官网 https://swagger.io/核心功能 生成接口说明文档生成接口测试工具 2、SpringBoot集成Swagger2 1&#xff09;、添加依赖 <!-- swagger2 --><!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --><depen…

[WUSTCTF2020]alison_likes_jojo 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 得到的 flag 请包上 flag{} 提交。 感谢 Iven Huang 师傅供题。 比赛平台&#xff1a;https://ctfgame.w-ais.cn/ 密文&#xff1a; 下载附件解压&#xff0c;得到两张jpg图片和一个文本文件。 解题思路&#x…

[DL]深度学习_Feature Pyramid Network

FPN结构详解 目录 一、概念介绍 二、结构详解 1、对比试验 2、特征图融合 3、结构详解 4、不同尺度预测 5、Proposal映射到预测特征层 一、概念介绍 Feature Pyramid Network (FPN)是一种用于目标检测和语义分割的神经网络架构。它的目标是解决在处理不同尺度的图像时…