前端加密攻防实战:深度解析与绕过技巧(上)

admin 2024年11月4日09:31:38评论26 views字数 4403阅读14分40秒阅读模式

点个关注,谨防走丢~

前端加密攻防实战:深度解析与绕过技巧(上)

作者简介

许理想,ID:Drea1v1,具备丰富的甲乙方安全工作经验,主要研究领域:代码审计、漏洞挖掘、红蓝对抗、数据安全等。

前言

为保证数据传输的完整性和机密性,越来越多的应⽤系统选择在前端对报⽂进⾏加密加签处理。这种方式无疑会增加安全测试⼈员的攻击成本,在⼀定程度上降低了⽹站遭受恶意攻击的⻛险。然⽽,随着技术的不断发展,与之对应的破解方法和破解工具也随之出现。本⽂旨在记录并分享我在前端加密绕过方面的实战经验,系列文章分上下两篇,分别以两个真实案例讲解前端加密的过程以及绕过方式,同时分别对所使用到的工具做了简单介绍。

本篇文章的案例⽹站没有对数据包加密,只是对请求报⽂进⾏了加签,如果修改请求报⽂,后端会识别到报⽂与签名值不⼀致,会进行拦截请求。

安全逻辑分析

先看请求报⽂,请求报⽂和返回报⽂都没有加密,修改请求参数data时,返回⾮法请求。可以确认⽹站有对报⽂做防篡改校验:

前端加密攻防实战:深度解析与绕过技巧(上)

现在要确认前端防篡改的具体逻辑是什么,查看请求包url中存在jsv、appkey、t、sign、api、dataType、timeout、userToken、c等多个参数,请求体中仅有⼀个data参数,已知修改data的值会拦截,经过尝试修改url中的参数appkey、t、sign三个值其中⼀个也会拦截。

前端加密攻防实战:深度解析与绕过技巧(上)

先尝试在js中搜索appKey中的值12574478,发现不是很多,全部都下⼀个断点,点击刷新重新发起请求:

前端加密攻防实战:深度解析与绕过技巧(上)

看了⼀眼右边,这个不是请求中对应的url吗?

前端加密攻防实战:深度解析与绕过技巧(上)

跳过继续执⾏下⾯的代码,参数l赋值为当前时间戳,s的值经过⼀个很⻓的匿名函数

前端加密攻防实战:深度解析与绕过技巧(上)

先跳过,看看下⾯还有什么,出现了请求体中的data参数。

前端加密攻防实战:深度解析与绕过技巧(上)

稍微往上⾯看看,出现上⾯分析的那⼏个参数,全在这⾥赋值了,突然警觉起来~,这⾥可以看到jsv是给的固定值2.6.2,appkey的值为i(12574478)⼀开始我搜索的请求包⾥的那个值,t是时间戳, sign 是s ,看着是⼀串随机字符串,是上⾯提到的通过匿名函数⽣成的。

前端加密攻防实战:深度解析与绕过技巧(上)

这⾥回到匿名函数看看结构,我把整个js扣了出来,折叠了⼀下函数内容,观察参数,传⼊了⼀个形参e ,这个e 是怎么来的呢?最后⼀⾏中多个变量拼接&符号⽣成的。(r.token + "&" + l + "&" + i + "&" + n.data)

前端加密攻防实战:深度解析与绕过技巧(上)

r.token是⼀个随机字符,通过搜索之前出现的数据包发现为Cookie中_m_h5_tk的值(估计是登录服务端返回的,每次请求都是⼀样,不变的话就没必要分析了),l是时间戳已经知道,i是appkey的值,n.data是请求体参数。⼤概了解参数时怎么来的,跟进函数看看传参的值是不是我们理解的那样。

前端加密攻防实战:深度解析与绕过技巧(上)

前端加密攻防实战:深度解析与绕过技巧(上)

可以看到内容是没问题的,到这⾥其实已经知道为什么改了appkey、t、data这⼏个参数会被拦截了吧?实际就是把这些参数的内容做了⼀个签名,只要内容变了,后端通过相同的⽅法重新计算新的签名与前端传进来的值⽐对,如果不同的话说明请求包被篡改了,也就返回⾮法请求的提示。

前端加密攻防实战:深度解析与绕过技巧(上)

ok,现在整体流程都清楚了,那要怎么绕过呢?以前,苦逼的我做法是通过前端断点暂停⼤法,⼿动调⽤函数⽣成想要的值。所谓的时停⼤法就是在浏览器进到断点调试时,直接在console上调⽤对应的函数。为什么需要暂停呢,因为不暂停,js缺少上下⽂环境就会报错,只有在当前断点的时刻才能正常执⾏。本案例不需要补环境,代码扣下来可直接运⾏。为什么要提到这个呢,因为本系列文章的第二篇案例使⽤的⼯具和这个原理有点类似,就是为了解决环境的问题,所以在这⾥先提⼀嘴。

判断是否需要补环境⽐较简单的⽅法是将代码复制到console运⾏,看看是否报错:

前端加密攻防实战:深度解析与绕过技巧(上)

调⽤函数没有报错:

前端加密攻防实战:深度解析与绕过技巧(上)

⼿⼯构造参数看看,这⾥我把data中的clientRequestId设置为任意的内容,重新⽣成sign:

前端加密攻防实战:深度解析与绕过技巧(上)

放到bp⾥⾯重放⼀下返回正常,没什么问题,完美:

前端加密攻防实战:深度解析与绕过技巧(上)

自动化生成签名

现在已经有了能直接调⽤的函数,下⾯将介绍⼀款⼯具可实现⾃动根据请求内容,⽣成签名。

mitmproxy是⼀款功能强⼤的⽹络抓包⼯具,⽀持HTTP和HTTPS等协议。该⼯具的优点在于其⾼度的可扩展性,允许⽤户根据⾃身需求定制开发插件(addons)。这些插件通过与mitmproxy内置的事件系统进⾏交互,能够在特定的处理节点介⼊并灵活地调整mitmproxy的⾏为模式。每当⼀个HTTP请求被系统捕获时,相应的插件即可监听该事件,并据此对请求或响应内容进⾏必要的修改。此外,mitmproxy还具备反向代理功能,能够将接收到的请求有效转发⾄上游服务器,进⼀步拓宽了其应⽤场景。mitmproxy有三种命令⽅式分别为mitmproxy(交互式命令⾏,可直接通过交互命令对报⽂进⾏操作)、mitmweb(提供⽹⻚图形化界⾯展示报⽂信息)、mitmdump(⽆交互命令⾏,仅显示少量内容),为简化操作本⽂使⽤mitmdump说明。

官⽹地址:

https://www.mitmproxy.org/

安装⽅法:

pip install mitmproxy

使⽤介绍在启动⼯具之前,需要编写⼀个⾃定义插件。以下是插件的⼀个简单模板以及mitmproxy提供的⼀些常⽤的函数,掌握这些基本够⽤,更多api和事件信息可查看官⽹

https://docs.mitmproxy.org/archive/v8/api/events.html
from mitmproxy import httpclass Sign:    #http事件,用于拦截http请求    def request(self,flow: http.HTTPFlow):         #打印日志的方法        ctx.log.info("We've seen %d flows" % self.num)        #获取请求url        url = flow.request.pretty_url        #获取请求体        body = flow.request.get_text()        #设置请求体        flow.request.set_text('xxxxx')        #获取请求方法        method = flow.request.method        #获取请求头字典        headers = flow.request.headers        #获取cookie字典        cookies = flow.request.cookies    #http事件,用于拦截http返回包    def response(self,flow: http.HTTPFlow):       #获取返回体        respBody = flow.response.get_text()       #获取返回请求头字典        headers = flow.response.headers       #设置返回报文        flow.response.set_text('xxxx')addons = [Sign()]

目前先理一下想要的效果:浏览器将请求报文给到bp时,在bp内修改data内容,自动修改sign值,重放报文后,服务器认为报文没被篡改不作拦截。

解决思路:将报文给到mitmproxy插件处理,插件自动生成sign并将原来的sign替换,重新生成数据包发到服务器。此时需要一个上游服务器,使用js函数根据bp提供的内容生成sign值,那么可以把生成sign的前端代码(扣代码)放到本地,然后调用execjs(python中执行js代码的模块)去执行。

前端加密攻防实战:深度解析与绕过技巧(上)

步骤⼀:创建⼀个js⽂件,把前端js代码复制到本地。

前端加密攻防实战:深度解析与绕过技巧(上)

步骤⼆:按照上⾯提供的模板编写插件,如下:

import requests,time,execjsfrom mitmproxy import httpfrom urllib.parse import unquote#读取js代码文件内容,后面调用方法使用js_code = open('sign.js','r',encoding='utf-8').read()AT_STR = '&'class Sign:    def request(self,flow: http.HTTPFlow):        #判断拦截报文的url是否为所关注的目标站点,这个根据实际情况设置,可以设置多个。本次仅有一个。        if 'xxx.xxxx.com' in flow.request.pretty_url:            #构造temp            list = []            #获取cookie中的token值,即原参数中的r.token。            h5Cookie = flow.request.cookies['_m_h5_tk']            h5Cookie = h5Cookie.split('_')[0]            #以目前时间生成时间戳,为什么不能用同一个?经测试,时间戳超过指定时间会被后端认为有问题拦截掉,为了避免这种情况发生,重新生成一个新的。            timeStr = str(int(time.time()*1000))            #获取query中的appkey的值            appkey = flow.request.query.get('appKey')            #获取请求报文            dataParam = flow.request.get_content().decode('utf-8')            #获取data的值,即data=abcd中abcd            dataParam = unquote(dataParam.split('=')[1])            #拼接关键字段,AT_STR为'&'字符            temp = h5Cookie + AT_STR + timeStr + AT_STR + appkey + AT_STR + dataParam            #调用generateSign函数            signText = self.generateSign(temp)            #将新生成的sign值重新赋值给query中的sign参数            flow.request.query['sign'] = signText            #将新生成的时间戳值重新赋值给query中的t参数            flow.request.query['t'] = timeStr    def generateSign(self,temp):        #调用execjs模块执行js代码,调用sign函数,并将sign值返回        sign = execjs.compile(js_code).call('sign',temp)        return sign#加载插件Signaddons = [Sign()]

步骤三:好了,现在已经做好所有准备⼯作,开始验证是否有效。启动mitm监听,mitmdump -s xxx.py -p port ,其中xxx.py是编写的py插件,port为代理监听端⼝。

前端加密攻防实战:深度解析与绕过技巧(上)

bp设置上游服务器为mitmproxy监听地址和端⼝:

前端加密攻防实战:深度解析与绕过技巧(上)

这⾥我把任意⼀个请求的包把参数改⼀下,sign都不带变的,发送成功。

前端加密攻防实战:深度解析与绕过技巧(上)

前端加密攻防实战:深度解析与绕过技巧(上)

看mitm的⽇志,有流量经过,打印输出新⽣成的sign,成功绕过验签。

前端加密攻防实战:深度解析与绕过技巧(上)

总结

本篇文章作为《前端加密攻防实战:深度解析与绕过技巧》的上篇,以只加签未加密的网站为例,介绍了如何分析安全逻辑、如何通过手工和工具两种方式绕过前端安全逻辑。下一篇文章将以即加密又加签的网站为例,继续深入解析前端攻防实战。

原文始发于微信公众号(安全有术):前端加密攻防实战:深度解析与绕过技巧(上)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月4日09:31:38
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   前端加密攻防实战:深度解析与绕过技巧(上)https://cn-sec.com/archives/3351889.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息