某次众测的加解密对抗

前言

起源于某次众测中,遇到请求包响应包全密文的情况,最终实现burp中加解密。

用到的工具有

  • sekiro(rpc转发)
  • flask(autodecoder自定义接口)
  • autodecoder(burp插件转发)

debug部分

开局搜索框,随意输入字符。

从burp查看后端请求,发现请求包响应包均为密文

猜测应该是前端进行了加密操作,接着尝试debug出加密逻辑。

先从启动器中寻找接口触发的函数,这里通过定位getData函数

然后通过F10跳过函数,最终到加密处如下

发现加密函数为Object(r["b"]),通过控制台打印它,双击即可跟进函数

具体定义如下。

观察be35包,当调用b的时候,返回了s,及AES加密。当调用a的时候,返回了o,及AES解密。分析这个AES的加解密,key和iv均不为硬编码,这也是后续RPC的最难点。

对于RPC来说,这一步需要我们将加解密函数添加到全局,也就是

window.enc=Object(r["b"]) //加密
window.dec=Object(r["a"]) //解密

添加完之后,还有key和iv需要解决。

这里当时临时解决办法是通过debug当时的key和iv,通过硬编码的形式来进行加解密。

js注入部分

首先需要在sekiro中新建group,不然匿名分组会慢很多。

由于这里使用的是sekiro的浏览器js环境,可参考官方文档,注入浏览器js代码

这里由于我进行的本地rpc,需要将wss协议更换为ws

var client = new SekiroClient("ws://localhost:端口号/business/register?group=分组名&clientId=" + Math.random());

在完成cleint创建后,还需要具体注册加解密的Action

下面是针对debug的函数做出的加解密方法注册。

client.registerAction("aes_enc", function (request, resolve, reject) {//加密
    resolve(enc(request["enc_par"],request["key"],request["iv"]); 
});

client.registerAction("aes_dec", function (request, resolve, reject) {//解密
    resolve(enc(request["dec_par"],request["key"],request["iv"]); 
});

其中 enc 调用的是debug时注册的全局加密函数,request["xxx"]为调用 sekiro http接口的参数名,其他用法可参考使用文档。

burp上游代理部分

这里使用的autodecoder这款burp插件的接口加解密来作为上游代理,这里通过python的flask框架来编写二层接口加解密。以下是加密接口实现,解密同理。

@app.route('/aes_encode', methods=["POST"])
def encrypt():
    param = request.form.get('dataBody')  # 获取  post 参数
    data = {
        "group": "分组名",
        "sekiro_token": "xxxxx", #在sekiro的管理页面
        "action": "aes_enc", #注册的action名字
        "enc_par": param,
        "bind_client": "设备名",
        "key": key,
        "iv": iv
    }
    res = requests.post(url, data)
    enc = json.loads(res.text)['data']
    return enc

需要注意的是bind_client参数为设备ID,这个参数需要加上,不然会导致多设备转发出错,参考官方文档。

bind_client参数位置如下。

做完这些部分之后,即可在burp的拦截、重放功能中对密文解密。

key和iv随机问题解决

由于当时临时解决办法为,将key和iv通过debug出来后,硬编码赋值给上游代理的flask,但后续刷新页面,key和iv却发生了变化。于是重新debug出key和iv的生成逻辑。

debug回到之前的加密处

带着之前的思路,加密处为

Object(r["b"])(e.data, b.dfg, b.cvb)

其中key、iv对应的b.dfg、b.cvb。而对象b的定义如下

也就是由 Object(h["o"])("randomRequest", !0) 生成。同样通过控制台跟进Object(h["o"])

来到 f(t,e) 函数,如下

具体代码如下

function f(e, t) {
            e = "bqzt_" + e;
            var a = "sessionStorage";
            if (/mqqbrowser/i.test(window.navigator.userAgent) && (a = "localStorage"),
            window[a]) {
                var i = window[a][e] || "";
                return t && i && (i = JSON.parse(i)),
                i
            }
            console.log("当前浏览器不支持sessionStorage")
        }

分析这段代码,发现是正则匹配是否是QQ浏览器的user-agent来判断存储位置,如果正则匹配满足 /mqqbrowser/i ,则存储e到localStorage,如果不满足,则e存储到sessionStorage

而这里的f(e,t)函数中,e是什么呢,这里我们直接查看sessionStorage,也就是会话储存,发现e就是AES加解密的key和iv。

debug到这一步,问题解决的关键就在于sessionStoragelocalStorage

当页面刷新时sessionStorage会发生变化,导致key和iv发生变化,我们设置的硬编码就失效了。而localStorage并不会随着页面刷新而重置,它存储于浏览器当前状态。

所以我们只需要将user-agent更换为QQ浏览器即可将bqzt_randomRequest存储进localStorage
这里解释一下为什么改为localStorage就能动态获取key和iv,因为在js注入后,存储的也是sessionStorage,刷新就会消失。而存储为localStorage之后,只要保持jsrpc注入的页面和具体渗透测试的页面处于同一浏览器即可。

最后一步,我们需要修改注册的action,将key和iv分别利用 localStorage 来获取。具体代码如下:

client.registerAction("aes_enc", function (request, resolve, reject) {
    resolve(enc(request["enc_par"],JSON.parse(localStorage.getItem("bqzt_randomRequest")).dfg,JSON.parse(localStorage.getItem("bqzt_randomRequest")).cvb));
});

到这问题基本解决了,autoDecoder中效果图如下。

后续笔者也成功通过此加解密技巧,成功挖掘出高危漏洞。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

<网络> 网络Socket编程基于TCP协议模拟简易网络通信

目录​​​​​​​ 前言: 一、字符串回响 (一)程序结构 (二)初始化服务器 (三)启动服务器 1. 处理连接请求 2. 业务处理 3. 回调函数 (四)填充server源文件 &…

公司刚招了一个5年测试,竟然连抓包都不会

大家都知道,无论是测试人员还是开发人员,移动端抓包都是必须掌握的关键技能。然而还有人在测试岗位上干了这么久,还是不懂如何进行抓包!今天就跟大家分享两款在日常工作中常用的抓包工具:Fiddler和Charles Fiddler和C…

94岁诺奖得主希格斯去世,曾预言「上帝粒子」的存在

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 一位用诗意的语言揭示宇宙秘密的人。 一位 94 岁伟大科学家的逝世,引发了人们广泛…

分布式事务方案与Seata详解

分布式事务与Seata详解 一、分布式事务1.什么是分布式事务2.分布式事务解决方案-2PC3.分布式事务解决方案-3PC4.分布式事务解决方案-TCC5.分布式事务解决方案-XA6.可靠消息最终一致性6.1 本地消息表6.2 事务消息 7.最大努力通知8.SAGA9.分布式事务解决方案思考 二、Seata 简介与…

pytesseract,一个超强的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个超强的 Python 库 - pytesseract。 Github地址:https://github.com/madmaze/pytesseract 在当今数字化时代,文字识别技术扮演着越来越重要的角色。…

基于sd的单分支和双分支方案

单分支: 1.ip-adapter 2.photomaker 3.CLE-Diffusion 4.powerpaint 5.videocomposer 6.animateanything 7.pixeldance 8.aniamtediff 双分支: 1.controlnet 2.instanceid 3.brushnet 4.ootdiffusion 5.MagicAnimate 7.animateanyone

《QT实用小工具·十七》密钥生成工具

1、概述 源码放在文章末尾 该项目主要用于生成密钥,下面是demo演示: 项目部分代码如下: #pragma execution_character_set("utf-8")#include "frmmain.h" #include "ui_frmmain.h" #include "qmessag…

qtablewidget 事件过滤器 鼠标事件不生效

1. 创建了一个MouseEventFilter类,它覆盖了eventFilter()方法来拦截鼠标按下事件。然后,我们将这个事件过滤器安装到了QTableWidget上 2.记得注册事件过滤器 3.这里是头文件 看一下就行 4.return true代表事件被处理,不需要再处理&#xff…

深入了解Redis——哨兵机制

三,Redis哨兵机制 Redis的哨兵机制主要是为了提高Redis主从模型下的可用性,能保证主节点异常发生时还能够正常的运作并进行故障转移。哨兵机制为了实现这一点提供了以下这些功能: 节点监控下线判断领导者选举slave选举故障转移 在介绍这些…

目标检测——车牌图像数据集

一、重要性及意义 车牌图像识别的重要性及意义主要体现在以下几个方面: 智能交通管理:车牌图像识别技术是智能交通系统(ITS)的核心组成部分。通过自动识别车辆车牌,可以实现对交通违章行为的自动记录和处理&#xff…

【数据库】数据库应用系统生命周期

目录 1.为什么提出”软件工程“的思想? 2.为什么提出”瀑布模型“?缺点是什么? 3.为什么提出”快速原型模型“? 4.为什么提出”螺旋模型“? 5.关于数据库的英文缩写。 6.模型设计中的3条设计主线:数…

OpenHarmony分布式软总线API调用测试工具 softbus_tool使用说明

softbus_tool 是 OpenHarmony 分布式软总线 API 调用测试工具,文件结构如下图所示。 softbus_tool 能够将软总线 interfaces 目录下的一些常用接口集中起来,供设备间搭建一些场景时使用(比如设备绑定、BR 组网,BLE 组网&#xff…

低成本高效益,电子画册才是品牌的重要选择

随着互联网的普及和数字化技术的进步,电子画册已成为许多品牌的重要选择。与传统印刷画册相比,电子画册具有低成本、高效益的优点,成为品牌宣传的新趋势。 具体来说,电子画册可以通过在线平台或移动设备轻松查看,无需额…

【学习】软件测试中为什么要进行接口测试?

接口测试是软件开发过程中不可或缺的一环,它主要是对软件系统中各个模块之间的接口进行测试,以验证它们是否能够正确地交互和协作。接口测试的目的是确保软件系统的各个部分能够无缝地协同工作,从而提高整个系统的质量和稳定性。 一、什么是接…

allegro图片导入及调整的详细方法

目录 1. 图片转换2. 图片导入3. 导入图片调整3.1 图层调整 1. 图片转换 allegro只能导入IPF格式的文件: 正常情况下我们的图片都是JPG、BMP或者其他常见格式,需要将之转换为IPF格式才能导入,这里有工具。 需要工具在此 ->BMP转IPF工具 …

JDBC笔记

文章目录 JDBC相关JDBC-API详解一、DriverManager1.DriverManager(驱动管理类)作用 二、Connection1.Connection(数据库连接对象)作用2.具体操作**获取执行SQL对象****事务管理** 三、Statement1.Statement作用执行SQL语句 四、ResultSet1.ResultSet(结果集对象)作用2.获取查询…

SpringBoot菜品分页查询模块开发(多表连接查询)

需要注意的地方 为什么创建VO类怎么进行多表连接查询分页查询的统一返回结果类PageResult分页查询Mapper的返回结果是Page<目标实体类> 需求分析与设计 一&#xff1a;产品原型 系统中的菜品数据很多的时候&#xff0c;如果在一个页面中全部展示出来会显得比较乱&…

C语言—每日选择题—Day68

第一题 1、运行以下C语言代码&#xff0c;输出的结果是&#xff08;&#xff09; #include <stdio.h> int main() {char *str[3] {"stra", "strb", "strc"};char *p str[0];int i 0;while(i < 3){printf("%s ",p);i;} retur…

代码随想录算法训练营Day50|LC123 买卖股票的最佳时机IIILC188 买卖股票的最佳时机IV

一句话总结&#xff1a;虽然是困难题&#xff0c;其实都只需要对122 买卖股票的最佳时机II稍作变形即可。 原题链接&#xff1a;123 买卖股票的最佳时机III 相较于买卖股票的最佳时机和股票II来说&#xff0c;本题加了最多操作两次的限制。那么这里实际上就可以直接用滚动数组…