渗透测试高级技巧(一):分析验签与前端加密

“开局一个登录框”

在黑盒的安全测试的工作开始的时候,打开网站一般来说可能仅仅是一个登录框;很多时候这种系统往往都是自研或者一些业务公司专门研发。最基础的情况下,我们会尝试使用 SQL 注入绕过或者爆破之类的常规手段,如果可以成功,那皆大欢喜;但是随着甲方系统研发的迭代与额外安全要求,简单的抓包重访变得非常困难:

秘技一:破解验签防篡改

签名验证(又叫验签或签名)是验证请求参数是否被篡改的一种常见安全手段,验证签名方法主流的有两种,一种是 KEY+哈希算法,例如 HMAC-MD5 / HMAC-SHA256 等,另外生成签名的规则可能为:username=&password=。在提交和验证的时候需要分别对提交数据进行处理,签名才可以使用和验证

在给请求签名的情况下,如果重访过程中,数据修改了然而签名没有修改,那就意味服务器可以因为“签名不一致”随时拒绝掉我们的用户请求。

为了方便大家理解这个过程,我们可以通过一个简单的案例向大家介绍这种前端安全防护技术:

1698827331_65420c432e7b716fc31f1.png!small?1698827331555

当我们把这个表单提交给后端之后,将会看到后端的验证结果:分别是 “签名验证成功”,“用户名密码验证失败”

1698827341_65420c4d32215de80eec3.png!small?1698827341706

这说明我们可以从网站提供的表单简单发起了一个可以过验签的请求,但是并不能过认证;当然能不能过认证都要看“缘分”了。

验签真的可以防爆破吗?

验签是一个很基础的对数据包完整性和篡改防护的保护策略,他在大多数时候可以应对简单的修改,例如:我们在 Yakit 手动劫持中,劫持到验证数据包,然后直接进行修改:

在这里插入图片描述

在这种情况下,我们想要重放数据包,从password这个字段入手,爆破一下密码,自然也是不行的:那么难道真的就一筹莫展了嘛?

1698827360_65420c606003d908fbadd.png!small?1698827360874

大家深入思考验签的流程,就很容易想到,只要修改数据的时候,连带签名一起修改掉就好了。那么我们应该如何做这个事情呢?首先用户需要很清楚如下几点:

  1. 大部分签名的逻辑都藏在前端 JavaScript 中;
  2. 签名中字段的顺序一般来说是有意义的,JavaScript 中的 Object Properties 是有顺序的;
  3. JavaScript 签名的算法可能用的算法库一般不需要用户手动实现,找出算法一般就可以开始实现了。

为了让大家更清楚这个过程,大家可以跟随笔者的操作一步一步复现分析过程:

1698827372_65420c6c81886b881f14d.png!small

我们通过浏览器操作直接定位到 HTML 元素(为了方便大家观察,我们直接把 HTML 元素复制在下面的代码块中):

<form id="json-form" class="mt-4">
<div class="mb-3">
<label for="username" class="form-label">UserName</label>
<input id="username" class="form-control" type="text">
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input id="password" class="form-control" type="text">
</div>
<button id="submit" type="submit" class="btn btn-primary">Submit</button>
</form>

``我们要记住id='json-form'这个表格内的内容,,在验签的时候,多半是需要操作 DOM 元素取值计算的。细心的读者可能发现了,这个表格和我们有时候见到的表格是不一样的,他没有action也没有method,一般来说,在没有这些东西情况下,有两种情况:

  1. (大概率)表单提交事件会忽略掉默认浏览器行为,直接通过 JavaScript 来操作的
  2. 表单只提交到当前页面使用默认的 method 方法

在看页面内容中,我们发现<script>中有一段 JavaScript 代码比较明显,从generateKeyEncryptDecrypt应有尽有,这个很明显这个表单就是通过 JS 去操作的了。

重新整理一下思路我们想到,JS 操作表单提交数据的话,一般有几种方式?笔者在这里列出一些基础的特性,大家可以有一个印象:

  1. 通过创建一个form元素然后执行他的submit方法来实现,一般来说特征代码是使用const formInstance = document.createElement("form"); ... ;formInstance.submit()
  2. 使用 AJAX:var xhr = new XMLHttpRequest(); ... xhr.open("POST", '/submit', true);
  3. 使用 jQuery Ajax:$.ajax(...)
  4. 通过 JavaScriptfetch函数实现
  5. 使用第三方库例如 Axios API 实现

1698827445_65420cb54fa86b4417586.png!small?1698827445825

我们通过上述描述的内容,可以很容易分析出这个表单提交和验签算法的基础逻辑:

  1. 生成一个 KEY,默认为 16 位数1234123412341234
  2. 从表单中获取用户填写的用户名和密码进入getData()函数中
  3. 用户数据用户名密码字符串排列拼接好之后,使用Encrypt函数为他计算签名
  4. 把计算的结果和 KEY 进行JSON.stringify(...)处理后通过fetch提交

因此,如果我们要重放这个请求,一定需要经过验签。对应的验签名逻辑根据描述其实非常好做,我们简单实用 Yaklang 来实现一下(验签的核心函数是 HMacSha256)这在 Yaklang 中是有对应的函数的,只需要调用即可

result = codec.HmacSha256("1234123412341234", "username=admin&password=123456")~
result = codec.EncodeToHex(result)
dump(result)
// (string) (len=64) "7d113a1544cd53ff6c527c865511be4f18d4372a7fa571dbc035f0fc12b2b092"

func sign(user, pass) {
return codec.EncodeToHex(codec.HmacSha256("123412341234", f`username=${user}&password=${pass}`)~)
}

``我们通过简单的函数封装,就实现了和 JavaScript 相同的计算结果,那么我们可以完整地实现一下 Web Fuzzer 对验签的爆破过程:

1698827475_65420cd35e26c45bbb102.png!small?1698827476085

我们编写了一个几行的函数来承载核心的签名功能:

func sign(user, pass) {
return codec.EncodeToHex(codec.HmacSha256("1234123412341234", f`username=${user}&password=${pass}`)~)
}

signRequest = result => {
pairs := result.SplitN("|", 2)
dump(pairs)
return sign(pairs[0], pairs[1])
}

``这两个函数在热加载中可以通过{{yak(signRequest|...)}}来调用,配合我们编写的标签,直接实现发包的时候签名,达到爆破的目的。

1698827526_65420d069bd85d7839c6b.png!small?1698827527144

通过设置 fuzztag 的变量,我们直接对签名进行动态修改并且每一次都能验签成功,实际上已经可以进行爆破了!那么很自然的,我们可以设置变量中的password直接对有签名验证的登录点进行爆破。

1698827540_65420d144fb8c0fdbf93f.png!small?1698827540665

签名并不能解决“明文密码传输”

当我们学会测试带验签的接口的基本技能之后,我们会自我反省这个保护措施其实只是增加了操作的复杂度和难度,并不是真正的能解决“防篡改防重放的问题”。

当然,我们的密码仍然在通信过程中“明文传输”;

“明文密码传输”的不合规项一直是一个备受争议的选项,甚至前些年大家觉得这就是用来“凑数”的安服报告内容。

但是戏剧性的是,随着一些甲方单位真的全 API 通信上了加密之后,普通测试手段失效了,大家不再轻视这个问题,开始广泛讨论“如何绕过前端加密进行安全测试”这类话题。

秘技二:渗透前端JS加密表单

当我们发现网站的管理员把“明文密码传输”这种问题拿上台面并且真的做了防护的时候,很多本来唾手可得的成果,突然就变得棘手。这要求我们老旧的工具需要进行升级,防护技术的更新换代自然要求安全测试技术也必须跟上。那么受到“使用 Yaklang 解决验签”技术的启发,我们其实可以使用同样的手段去解决一下明文密码传输的问题。

那么,我们将会以:CryptoJS AES的前端加密技术来作为案例,为大家介绍这种技术(类似验签中的案例):我们使用 Vulinbox 中的CryptoJS AES(CBC) 前端加密登陆表单这个靶场来为大家介绍这种防护的测试方案。

在这里插入图片描述

了解你的对手

在安全测试的过程中,AES-CBC/ECB 的组合可能是我们最常遇到的两种,很多同学对这两种组合其实并不清楚,那么我们应该如何测试这种相对比较常见的前端加密防护呢?工欲善其事,必先利其器,我们在测试之前,必须对基本的 JavaScript 加密的前端技术有一定认知:

前端加密一般常用的是两个库,CryptoJS 和 jsrsasign,他们彼此侧重点其实是不一样的:

  1. CryptoJS 主要提供 AES,SHA,HMAC,PBKDF2 等加密算法,但是他不提供非对称公钥 RSA 或者椭圆曲线(ECC)算法;
  2. jsrsasign 主要提供的签名和非对称加密算法,比如 RSA / ECC 等,除此之外,JWT 的验证,X.509 的证书解析等也有借口

这两个前端的关键加解密库对应的功能其实是互补的,并不能说我们只了解一个就能解决问题。在这一系列的教程中,我们也会为大家介绍他们各自擅长的加密场景和安全测试方法。

但是读者可千万不能认为前端的加密解密只有这两个库,事实上这两个库只是被用的多而已,还有一些更“官方”支持的库。

Chrome 的cryoto.subtle也是一个非常典型的加解密库,大家遇到的时候不要慌乱,他对 RSA 的支持也是可以实现加解密的。

还有国密商密算法系列,SM2 椭圆曲线,SM4 等,我们之后将会为大家依次介绍。

对于AES的CBC模式和ECB模式,我们需要知道他们的区别和联系才能方便后面的计算:

加密方式AES-CBCAES-ECB
IV(初始块)需要不需要
KEY 的长度16/24/32 字节16/24/32 字节
加密后特征与前一个密文进行异或,明文块相同,密文不一定相同明文是静态的 - 两个明文相同,那么他们密文也相同

对于 CryptoJS 来说,我们需要记住下面几个易错点:

  1. key = CryptoJS.enc.Utf8.parse(...)是常见的构建加密密钥的代码,通过这种方式构建出来的代码,直接调用key.toString()得到的数据实际上是原值进行十六进制编码的结果
  2. 如果想要得到 key 的 Base64 编码需要key.toString(CryptoJS.enc.Base64)
  3. 如果需要得到最原始的 key 的值(Utf8),则需要key.toString(CryptoJS.enc.Utf8)
  4. 如果 CryptoJS 的密码不够16/24/32字节的时候,他的会首先使用NULL(0x00)补全到对应位数,如果超过了位数,将会把多余的字节丢掉:

当然,所有 CryptoJS 中的字符串都遵循基本相同的规律。

分析加解密JS代码

读者通过了解我们上述的 JavaScript 加解密介绍,很容易能分析懂这个加密解密的实际过程关键点如下:

在这里插入图片描述

  1. 密钥被硬编码(1234123412341234)
  2. IV 是随机生成,也可以给一个固定值

根据这个基本分析,我们再来审视这个页面将会有新的理解:

IV 和 KEY 不变的话,加密的内容就不会变,我们只需要尝试使用 Yaklang 把这个密文用 IV 和 KEY 把内容解密,就可以验证了。``

data = {
"data": "lvIsXDQECZuulFJf4FsG+MGESw+NHG0sp78Gz7uuFvYuABq/H4aHT7RDpNUoV5Yc",
"key": "31323334313233343132333431323334",
"iv": "0e32a6c40da89058b6451c717d648cb7"
}
keyBytes = codec.DecodeHex(data.key)~
ivBytes = codec.DecodeHex(data.iv)~
a = codec.AESCBCDecryptWithPKCS7Padding(keyBytes, codec.DecodeBase64(data.data)~, ivBytes)~
println(string(a))
// {"username":"admin","password":"123456"}

我们发现解密出的内容非常符合预期,那么我们就可以着手准备我们的热加载代码了,需要模拟用户端的加密技术。为此我们编写一个热加载函数:

// {{base64({{yak(aescbc|{"username":"admin","password":"{{x(pass_top25)}}"})}})}}
aescbc = result => {
result = codec.AESCBCEncryptWithPKCS7Padding(
codec.DecodeHex(`31323334313233343132333431323334`)~, 
result, 
codec.DecodeHex(`0e32a6c40da89058b6451c717d648cb7`)~,
)~
return string(result)
}

``这个加密函数其实非常简单,我们放入热加载代码之后,调试出一个可用的 Payload,然后再 Web Fuzzer 种尝试进行爆破;检查一批发送成功的结果。

1698827641_65420d79e1b6f101cf22d.png!small?1698827642785

成功爆破

在我们基础验证之后,根据前面的一些经验,我们可以使用高级配置中的“变量”来加载我们的字典,达到爆破的目的:

1698827650_65420d822bca89df582bd.png!small?1698827651166

中场休息:

经过上面的操作,读者跟随我们的引导,在 Vulinbox 应该基本可以完成一些基本前端加密场景的渗透工作了。但是真实的场景其实很多要比我们实现的这几个靶场要复杂得多,Yakit Web Fuzzer 的更深层次的技术我们仍然没有办法在短短这一篇中给大家介绍完全,在接下来的篇幅中,我们会在为大家介绍一些更复杂更高级的前端安全防护的对抗技术:

  1. 动态加载密钥 Key 的 AES 加密防护对抗
  2. SM2 + SM4 的加密防护对抗
  3. 动态加载密钥的 RSA-OAEP 加密对抗

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

在这里插入图片描述

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

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

相关文章

开源计算机视觉库OpenCV详解

目录 1、概述 2、OpenCV详细介绍 2.1、OpenCV的起源 2.2、OpenCV开发语言 2.3、OpenCV的应用领域 3、OpenCV模块划分 4、OpenCV源码文件结构 4.1、根目录介绍 4.2、常用模块介绍 4.3、CUDA加速模块 5、OpenCV配置以及Visual Studio使用OpenCV 6、关于Lena图片 7、…

简于外 强于内,联想全新ThinkCentre M90a Pro Gen4以强劲性能开启商用新体验

近日&#xff0c;联想发布了最新一代商用台式一体机联想ThinkCentre M90a Pro Gen4。作为联想ThinkCentre M大师系列的旗舰产品&#xff0c;其配备了优质的显示屏&#xff0c;拥有强大的性能和稳定安全的特性&#xff0c;能够满足多样的工作场合&#xff0c;为商用一体机的行业…

面试题:你怎么理解System.out.println() ?

文章目录 首先分析System源码out源码分析println分析拓展知识点 你如何理解System.out.println() ? 学了这么久的面向对象编程&#xff0c;那如何用一行代码体现呢&#xff1f; 如果你能自己读懂System.out.println()&#xff0c;就真正了解了Java面向对象编程的含义 面向对…

Ajax入门-Express框架介绍和基本使用

电脑实在忒垃圾了&#xff0c;出现问题耗费了至少一刻钟time&#xff0c;然后才搞出来正常的效果&#xff1b; 效果镇楼 另外重新安装了VScode软件&#xff0c;原来的老是报错&#xff0c;bug。。&#xff1b; 2个必要的安装命令&#xff1b; 然后建立必要的文件夹和文件&…

MAX/MSP SDK学习07:list传递

实现自定义Obejct&#xff0c;要求将传入的一组数据100后传出。 #include "ext.h" #include "ext_obex.h" typedef struct _listTrans {t_object ob;void* outLet;t_atom* fArr;long listNum;} t_listTrans;void* listTrans_new(t_symbol* s, long arg…

【资深硬件工程师总结-千兆以太网设计指南】

文章目录 01通用PCB布线指南02标志焊盘中的接地过孔区示例03EMI注意事项04ESD注意事项 资深硬件工程师总结-千兆以太网设计指南 本应用笔记旨在帮助客户使用Microchip的10/100/1000 Mbps以太网器件系列设计PCB。本文档提供有关PCB布线的建 议&#xff0c; PCB 布线是保持信号完…

想分析全国用电及煤气、液化石油气供应利用情况,这部分数据对你有帮助!

随着经济的发展和人民生活水平的提高&#xff0c;能源的需求量越来越大。其中&#xff0c;电力和煤气、液化石油气等能源的供应利用情况与我们的日常生活息息相关。 今天我们根据《中国城市统计年鉴》统计的中国地级及以上城市的煤气及液化石油气供应及利用情况的指标&#xff…

【并发编程】ThreadLocal详解与原理

&#x1f4eb;作者简介&#xff1a;小明Java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

Redis整数集合

前言 整数集合(intset)是集合键的底层实现之一&#xff0c;当一个集合只包含整数值元素&#xff0c;并且这个集合的元素数量不多时&#xff0c;Redis就会使用整数集合作为集合键的底层实现。 一. 整数集合的实现 1.1 结构 整数集合(intset)是Redis用于保存整数值的集合抽象数据…

【Linux】进程间通信——进程间通信的介绍和分类、管道、匿名管道、命名管道、匿名管道与命名管道的区别

文章目录 进程间通信1.进程间通信的介绍1.1目的和发展 2.进程间通信分类3.管道3.1匿名管道3.1.1匿名管道的原理&#xff08;文件角度&#xff09;3.1.2匿名管道的原理&#xff08;内核角度&#xff09;3.1.3管道读写规则3.1.4管道特点 3.2命名管道3.2.1创建命名管道3.2.2命名管…

【计算机网络学习之路】TCP socket编程

文章目录 前言一. 服务器1. 初始化服务器2. 启动服务器 二. 客户端三. 多进程服务器结束语 前言 本系列文章是计算机网络学习的笔记&#xff0c;欢迎大佬们阅读&#xff0c;纠错&#xff0c;分享相关知识。希望可以与你共同进步。 本篇博客基于UDP socket基础&#xff0c;介绍…

【SpringCloud】认识微服务、服务拆分以及远程调用

SpringCloud 1.认识微服务 1.1单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署 单体架构的优缺点&#xff1a; 优点&#xff1a; 架构简单&#xff0c;部署成本低 缺点&#xff1a; 耦合度高&#xff08;维护困难&#x…

设备状态监测与故障诊断系统的作用

随着工业生产的发展和技术的进步&#xff0c;设备状态监测与故障诊断系统在工业领域中扮演着越来越重要的角色。这一系统通过实时监测设备的状态和参数&#xff0c;及时发现潜在的故障&#xff0c;并提供预警信号&#xff0c;以降低生产中断、提高安全性和维护效率。以下将详细…

Django 模型和Admin站点管理(三)

一、定义模型 &#xff08;1&#xff09; 创建模型类&#xff0c;必须要继承自 models.Model from django.db import models# Create your models here. #设计数据库 #创建模型 class UserModel(models.Model):namemodels.CharField(max_length30) #对应于SQL name varchar(30…

慕尼黑电子展Samtec Demo | 回环测试带来Samtec产品组合优异表现

【摘要/前言】 大家好&#xff01;Electronica虎家展台Demo系列回来咯。 实践出真知&#xff0c;再好的纸面数据都不如来一场实际的测试和演示。Samtec团队始终在努力为客户带来卓越的产品和优质服务。而这其中&#xff0c;Demo演示的存在至关重要。演示过程可以为大家带来了…

ubuntu编译sqlite3并使用

SQLite3是一种轻量级的关系型数据库管理系统&#xff0c;它是在C语言基础上实现的。SQLite3具有许多优点&#xff0c;例如&#xff1a; 1.灵活&#xff1a;它可以在多种操作系统上运行&#xff0c;并且可以将多个数据库文件合并成一个文件。 2.易于使用&#xff1a;SQLite3使用…

“云浮云福保”暖心回归! 保障升级价格不变,医保个账可为全家缴费!

11月22日&#xff0c;2024年“云浮云福保”项目启动会在广东省云浮市迎宾馆成功举办。记者在会上获悉&#xff0c;“云浮云福保”是在云浮市医疗保障局、云浮市金融工作局、国家金融监督管理总局云浮监管分局指导下&#xff0c;的指导下&#xff0c;由中国人民财产保险股份有限…

网络安全之渗透测试入门准备

渗透测试入门所需知识 操作系统基础&#xff1a;Windows&#xff0c;Linux 网络基础&#xff1a;基础协议与简单原理 编程语言&#xff1a;PHP&#xff0c;python web安全基础 渗透测试入门 渗透测试学习&#xff1a; 1.工具环境准备&#xff1a;①VMware安装及使用&#xff1b…

Modbus转Profinet网关连接PLC与天信流量计通讯案例

本文将为您详细介绍如何成功连接PLC与天信流量计&#xff1a;从选择合适的Modbus转Profinet网关开始&#xff0c;到设置网关以实现通讯连接&#xff0c;还会涵盖部署和故障排除过程中可能遇到的一些问题。 首先&#xff0c;选择合适的Modbus转Profinet网关至关重要。我们选用基…

竞赛python区块链实现 - proof of work工作量证明共识算法

文章目录 0 前言1 区块链基础1.1 比特币内部结构1.2 实现的区块链数据结构1.3 注意点1.4 区块链的核心-工作量证明算法1.4.1 拜占庭将军问题1.4.2 解决办法1.4.3 代码实现 2 快速实现一个区块链2.1 什么是区块链2.2 一个完整的快包含什么2.3 什么是挖矿2.4 工作量证明算法&…