【JSrpc破解前端加密问题】

news2024/9/20 4:02:19

目录

一、背景

二、项目介绍

三、JSrpc 处理前端加密步骤


一、背景

  解决日常渗透测试、红蓝对抗中的前端密码加密问题,让你的爆破更加丝滑;降低js逆向加密的难度,降低前端加密逻辑分析工作量和难度。

二、项目介绍

  运行服务器程序和js脚本 即可让它们通信,实现调用接口执行js获取想要的值;

实现原理:在网站的控制台新建一个WebScoket客户端链接到服务器通信,调用服务器的接口 服务器会发送信息给客户端 客户端接收到要执行的方法执行完js代码后把获得想要的内容发回给服务器 服务器接收到后再显示出来。具体项目地址和食用细节参考:https://github.com/jxhczhl/JsRpc

三、JSrpc 处理前端加密步骤

第一步 构建RPC通信环境

浏览器中访问目标网站,注入rpc服务端代码到浏览器中:

服务端代码如下:

function Hlclient(wsURL) {
    this.wsURL = wsURL;
    this.handlers = {
        _execjs: function (resolve, param) {
            var res = eval(param)
            if (!res) {
                resolve("没有返回值")
            } else {
                resolve(res)
            }

        }
    };
    this.socket = undefined;
    if (!wsURL) {
        throw new Error('wsURL can not be empty!!')
    }
    this.connect()
}

Hlclient.prototype.connect = function () {
    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.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;
    return true

}

//收到消息后这里处理,
Hlclient.prototype.handlerRequest = function (requestJson) {
    var _this = this;
    try {
        var result = JSON.parse(requestJson)
    } catch (error) {
        console.log("catch error", requestJson);
        result = transjson(requestJson)
    }
    //console.log(result)
    if (!result['action']) {
        this.sendResult('', 'need request param {action}');
        return
    }
    var action = result["action"]
    var theHandler = this.handlers[action];
    if (!theHandler) {
        this.sendResult(action, 'action not found');
        return
    }
    try {
        if (!result["param"]) {
            theHandler(function (response) {
                _this.sendResult(action, response);
            })
            return
        }
        var param = result["param"]
        try {
            param = JSON.parse(param)
        } catch (e) {}
        theHandler(function (response) {
            _this.sendResult(action, response);
        }, param)

    } catch (e) {
        console.log("error: " + e);
        _this.sendResult(action, e);
    }
}

Hlclient.prototype.sendResult = function (action, e) {
    if (typeof e === 'object' && e !== null) {
        try {
            e = JSON.stringify(e)
        } catch (v) {
            console.log(v)//不是json无需操作
        }
    }
    this.send(action + atob("aGxeX14") + e);
}

function transjson(formdata) {
    var regex = /"action":(?<actionName>.*?),/g
    var actionName = regex.exec(formdata).groups.actionName
    stringfystring = formdata.match(/{..data..:.*..\w+..:\s...*?..}/g).pop()
    stringfystring = stringfystring.replace(/\\"/g, '"')
    paramstring = JSON.parse(stringfystring)
    tens = `{"action":` + actionName + `,"param":{}}`
    tjson = JSON.parse(tens)
    tjson.param = paramstring
    return tjson
}

 如下注入至浏览器中,并连接通信环境

// 注入环境后连接通信
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zzz");
// 可选  
//var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zzz&clientId=hliang/"+new Date().getTime())

启动我们的中间监听器,可以看到有上线:

接口调用说明:

  • /list :查看当前连接的ws服务 (get)
  • /ws :浏览器注入ws连接的接口 (ws | wss)
  • /wst :ws测试使用-发啥回啥 (ws | wss)
  • /go :获取数据的接口 (get | post)
  • /execjs :传递jscode给浏览器执行 (get | post)
  • /page/cookie :直接获取当前页面的cookie (get)
  • /page/html :获取当前页面的html (get)

尝试调用浏览器ws接口并传入js代码

import requests

js_code = """
(function(){
    console.log("test")
    return "执行成功"
})()
"""

url = "http://localhost:12080/execjs"
data = {
    "group": "zzz",
    "code": js_code
}
res = requests.post(url, data=data)
print(res.text)

如下就证明成功实现了rpc通信和接口调用:

第二步处理加密

加密函数寻找:

定位加密函数,抓包分析,加密登录接口位于/api/sys_yonghua/login_web,全局搜索接口login_web

断点分析后,hook插桩函数和方法为:

const processedParam = v()(param); 
    const encryptedValue = n["default"].prototype.$AesDesHelper.AesOrDes_Encrypt(processedParam);

v()进行md5加密,模块n["default"].prototype.$AesDesHelper中的AesOrDes_Encrypt(l)方法对md5后的值进行加密,加密方法知道之后,接下来就是注册函数方法了。

注册函数方法:

1、浏览器控制台注册无参数方法


// 注册一个方法 第一个参数hello为方法名,
// 第二个参数为函数,resolve里面的值是想要的值(发送到服务器的)
demo.regAction("hello", function (resolve) {
    //这样每次调用就会返回“yesyesyesyes+随机整数”
    var Js_sjz = "好困啊"+parseInt(Math.random()*1000);
    resolve(Js_sjz);
})

无参接口调用:

2、浏览器控制台注册带参数方法

demo.regAction("md5", function (resolve, param) {
    // 确保 v() 可以访问并返回一个处理后的值
    const processedParam = v()(param); 
    const encryptedValue = n["default"].prototype.$AesDesHelper.AesOrDes_Encrypt(processedParam);
    resolve(encryptedValue);
});

带参param接口调用,即可实现本地浏览器前端加密:

第三步python脚本批量处理

导入密码字典:

python脚本调用接口进行批量处理加密:

import requests
import threading

path = "http://127.0.0.1:12080/go?group=zzz&action=md5&param="
encrypt_list = []

def GetEncrypt(password):
    url = path+'"'+password+'"'
    response = requests.get(url=url)
    if response.status_code == 200:
        encrypt_list.append(response.json()["data"])
        print(response.json()["data"])
    else:
        return {"status": response.status_code, "error": "Request failed"}


def MultProcess():
        threads = []
        with open("password.txt",'r') as file:
            for password in file:
                thread = threading.Thread(target=GetEncrypt,args=(password,))
                threads.append(thread)
                thread.start()
            for i in threads:
                i.join()

if __name__ == '__main__':
    print("开始加密处理")
    MultProcess()
    with open("after_encrypt.txt",'w') as file:
        for i in encrypt_list:
            file.write(i.strip()+"\n")
    print("加密处理结束")




加密后的字典:

最后配合burpsuite实现爆破:

    

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

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

相关文章

解锁生命活力密码!帕金森患者的专属锻炼秘籍,让每一步都稳健前行

在这个快节奏的时代&#xff0c;健康成为了我们最宝贵的财富之一。然而&#xff0c;对于帕金森病患者而言&#xff0c;身体的逐渐僵硬、运动能力的下降&#xff0c;似乎给生活按下了减速键。但请相信&#xff0c;科学的锻炼方法&#xff0c;就是那把重启生命活力的钥匙&#xf…

时间复杂度的常用符号+渐进时间复杂度分析

时间复杂度的常用符号 Θ \Theta Θ 如果 f ( n ) Θ ( g ( n ) ) f(n)\Theta(g(n)) f(n)Θ(g(n))&#xff0c;则 f ( n ) f(n) f(n) 与 g ( n ) g(n) g(n) 同阶。&#xff08;阶是指 f ( n ) f(n) f(n) 的指数&#xff0c;比如 n 2 n^2 n2 高于 n n n&#xff09; O O …

OJ在线评测系统 登录页面开发 前端后端联调实现全栈开发

前端 登录页面就是一个让用户输入账号和密码的表单 使用acro组件 先写布局 <a-form-item field"userAccount" label"账号"><a-input v-model"form.userAccount" placeholder"请输入账号" /></a-form-item><a-…

msvcp140.dll丢失如何解决?msvcp140.dll丢失的多种解决方法

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcp140.dll丢失”。这个错误通常会导致某些应用程序无法正常运行&#xff0c;给用户带来很大的困扰。那么&#xff0c;当我们遇到msvcp140.dll丢失的情况时&#xff0c;应该如何解决呢&a…

office2016 增强版 KMS

第一步&#xff1a; 用管理员权限登陆&#xff1a;Windows PowerShell &#xff08;安装最新的 PowerShell&#xff0c;了解新功能和改进&#xff01;https://aka.ms/PSWindows&#xff09; 第二步&#xff1a; C:\Windows\system32> cd C:\Program Files\Microsoft Off…

表情包创作、取图小程序端(带流量主)

小程序永久免费&#xff0c;无任何广告&#xff0c;无任何违规功能&#xff01; 小程序具备以下功能有&#xff1a; 支持创作者加入 支持在线制作表情包 使用说明 表情包必备工具&#xff0c;一款专属于你的制作表情包工具&#xff0c;斗图必备神器

macOS平台编译MAVSDK源码生成mavsdk库与mavsdk_server服务可执行文件

克隆源码: 克隆命令 git clone https://github.com/mavlink/MAVSDK.git --recursive 克隆成功如下: 生成makefile (只生成mavsdk库) cmake -Bbuild/default -DCMAKE_BUILD_TYPE=Debug -H. 指定安装目录与生成目录: cmake -Bbuild/macos -DCMAKE_BUILD_TYPE=Debug -…

C++初阶:STL详解(五)——vector的模拟实现

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C&#xff1a;由浅入深篇 小新的主页&#xff1a;编程版小新-CSDN博客 前言&#xff1a; 我们前面已经了解了vecto…

化妆风格识别系统源码分享

化妆风格识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

对话框按钮检测系统源码分享

对话框按钮检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

不会JS逆向也能高效结合Scrapy与Selenium实现爬虫抓取

1. 创建基础的scrapy项目 1.1 基础项目 在pycharm中安装scrapy框架 pip install scrapy 创建项目 scrapy startproject 项目名称 我们现在可以看到整体文件的目录&#xff1a; firstBlood ├── firstBlood # 项目跟目录 │ ├── init.py │ ├── items.py # 封装数…

leetcode438找到字符串种所有异位词

我的思路 先计算子串的字符的ascll码值的和&#xff0c;看看这个值是否相等&#xff0c;我认为可以筛掉一一部分就是子串和要比较的串排序比较是否相等 但是超时&#xff0c;样例太长了 题解思路 class Solution {public List<Integer> findAnagrams(String s, String…

csgo使用服务器一键开服联机

1、购买后登录服务器&#xff08;百度莱卡云游戏面板&#xff09; 登录面板的信息在绿色的登陆面板按键下方&#xff0c;不是你的莱卡云账号 进入控制面板后会出现正在安装的界面&#xff0c;游戏将近40G需要&#xff0c;安装时间相比较长&#xff08;如超过30分钟处于安装中请…

Carnivo嘉年华韩毅:好产品本身能吸引消费者 | SMARTIES CHINA 2024终审报道③

Carnivo嘉年华整合营销执行合伙人 韩毅 近日&#xff0c;SMARTIES CHINA 2024终审活动在苏州音昱水中天落下帷幕。来自各行业的40位品牌广告主代表&#xff0c;历时两天时间&#xff0c;通过紧张的评审和精彩的讨论&#xff0c;从178个优秀入围案例中评选出了每个类别的金银铜…

C++ 类和对象(中) 构造、析构、(运算符重载)赋值运算符、const成员函数等;有c语言基础更好

在最开始如果有些&#xff0c;看不懂可以去看上一篇 -->类和对象 上 阅读时要结合代码一起思考 学习完日期类可以看看以下oj题 KY111 日期差值 计算一年的第几天 1. 类的默认成员函数 默认成员函数&#xff0c;编译器会自动生成的成员函数被成为默认成员函数&#xff0c…

Excel导入数据

"update user set long1 "&C2&",long2 "&D2&" where code "&A2&";" excel怎么按逗号把数据分列? excel一列数字逗号隔开分列数据技巧_excel_办公软件_软件教程_脚本之家 excel怎么按逗号把数据分列? ex…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第四集:制作更多的敌人

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作敌人僵尸虫Zombie 1.公式化导入制作僵尸虫Zombie素材2.制作僵尸虫Zombie的Walker.cs状态机3.制作敌人僵尸虫的playmaker状态机二、制作敌人爬虫Climber…

C语言程序设计(进阶)

肆意张扬的我们都不会是烂尾的诗集。 2.整型在内存中的存储 我们之前讲过一个变量的创建是要在内存中开辟空间的。空间的大小是根据不同类型而决定的。 2.1原码、反码、补码 数值有不同的表现形式&#xff1a;2进制、8进制、10进制、16进制 其中整数的2进制表示也有三种形式&…

毕业论文写作会用到的AI软件!一定不能错过的18个网站!(务必收藏)

AI毕业论文写作它可以提供论文摘要、大纲、选题确立等多种写作辅助&#xff0c;还能帮助我们完成开题报告、实验报告、辩论灵感等内容。无论是文章纠正、批改&#xff0c;还是改写降重&#xff0c;它都能轻松搞定。甚至连论文致谢、创新创业计划书等都能为我们提供帮助。 以下…

缓存穿透 问题(缓存空对象)

文章目录 1、缓存穿透2、缓存空对象3、AlbumInfoApiController --》getAlbumInfo()4、AlbumInfoServiceImpl --》getAlbumInfo()5、RedisConstant6、请求缓存不存在的数据 1、缓存穿透 2、缓存空对象 3、AlbumInfoApiController --》getAlbumInfo() GetMapping("getAlbumI…