前端加解密对抗encrypt-labs
前言
项目地址:https://github.com/SwagXz/encrypt-labs
作者:SwagXz
现在日子越来越不好过了,无论攻防、企业src还是渗透项目,总能看到大量的存在加密的网站,XZ师傅的前端加密靶场还是很值得做一做的,环境很贴合实战会遇到的一些情况,本人web小菜鸡练完之后反正是收获颇丰,推荐给各位师傅。
之前自己在学习前端加解密经常遇到加密解不了的情况;之后慢慢看师傅们的文章,也学到了很多绕过技术,于是写了个简单的靶场,为之后的师傅们铺路学习,加密方式列出了我经常见的8种方式包含非对称加密、对称加密、加签以及禁止重放的测试场景,比如AES、DES、RSA,用于渗透测试加解密练习。希望可以帮助到最近在学习这块知识的师傅,靶场函数.很简单,和实战相比还是差的有点多,不过应该够入门了
默认密码:admin/123456
http://82.156.57.228:43899 (混淆)
http://82.156.57.228:43899/easy.php (无混淆)
加解密插件/工具
burp自动加解密插件autoDeceder:https://github.com/f0ng/autoDecoder
这个插件可以帮忙处理常见的AES、DES、SM4、SM2、RSA等加密,灰常好用

还有个浏览器插件:Ctool 程序开发常用工具:https://ctool.dev/
直接在谷歌商店或者火狐商店即可下载
也是可以对常见的加密方式进行加密解密,这个适用的加解密方式更多,如果只是用于验证加解密情况的话,这个插件会方便很多

encrypt-labs
使用无混淆的进行测试说明
http://82.156.57.228:43899/easy.php (无混淆)
admin/123456
【第一关】AES固定key
抓包发现数据包被加密了:加密参数为encryptedData

直接跟进js查看,直接在进入位置下断点,再次抓包

一个断点直接找到加密后的数据和加密前的数据,向上查找,发现是用AES加密
function sendDataAes(url) {const formData = {username: document.getElementById("username").value,password: document.getElementById("password").value};const jsonData = JSON.stringify(formData);const key = CryptoJS.enc.Utf8.parse("1234567890123456");const iv = CryptoJS.enc.Utf8.parse("1234567890123456");const encrypted = CryptoJS.AES.encrypt(jsonData, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7}).toString();const params = `encryptedData=${encodeURIComponent(encrypted)}
根据断点信息可知:
AES加密,CBC模式,PKCS5Padding
key:1234567890123456 / iv:1234567890123456
autoDecoder
配置数据包自动加解密
输入key / iv,设置正则表达式,正确设置正则表达式之后才可以实现自动解密

配置需要加解密的域名

尝试重放

【第二关】AES服务端获取Key
点击第二关抓包,可以获取到两个数据包,一个是服务端返回的key和iv,一个是登录数据包

经过测试发现,重发数据包该key和iv,发现key和iv短时间内不会发生变化,应该是服务端和客户端断连之前,key和iv都会保持不变

{"aes_key":"OUd4SEqDsA1GP2l8WszZnQ==","aes_iv":"RQenJ2Hszn1p7Q6poVngFQ=="}
查看js数据,确定为AES加密

autoDecoder


【第三关】RSA加密
抓包查看:加密参数是data

进入eazy.js下断点,往上查看,很容易获取到了publickey
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi
NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM
DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb
ocDbsNeCwNpRxwjIdQIDAQAB
-----END PUBLIC KEY-----

经确认为RSA加密,RSA加密需一个公钥,解密需要私钥,没有私钥,只能尝试加密
autoDecoder


【第四关】AES+Rsa加密
抓包查看

下断点往上查看

function sendDataAesRsa(url) {const formData = {username: document.getElementById("username").value,password: document.getElementById("password").value};const jsonData = JSON.stringify(formData);const key = CryptoJS.lib.WordArray.random(16);const iv = CryptoJS.lib.WordArray.random(16);const encryptedData = CryptoJS.AES.encrypt(jsonData, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7}).toString();const rsa = new JSEncrypt();rsa.setPublicKey(`-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi
NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM
DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb
ocDbsNeCwNpRxwjIdQIDAQAB
-----END PUBLIC KEY-----`);const encryptedKey = rsa.encrypt(key.toString(CryptoJS.enc.Base64));const encryptedIv = rsa.encrypt(iv.toString(CryptoJS.enc.Base64));
被加密的参数是formData也就是"{"username":"admin","password":"123456"}",经过AES加密,且加密使用的key和iv是16位随机数、得到encryptedData
之后对key和iv进行rsa加密得到encryptedKey和encryptedIv
再将这三个参数传入数据包中,发包进行验证
现在想办法将随机16位的key和iv进行固定,右键选择替换内容,使用本地替换的方式将key和iv固定下来,就选择之前第一关的key和iv即可


再次下断点,查看是否修改成功,可以看到已经修改成功,key和iv变成了1234567890123456


成功替换encryptedData,其中加密的key和iv经过测试似乎不用替换也能通过,就不进行加解密操作了
【第五关】Des规律Key
抓包查看,可以看到只对password进行了加密

进入js下断点抓包

可以看到就是简单的DES加密,key和iv都使用了username的值
key是八位,如果username不满8位,则用6补满
iv是八位,9999+username的前四位
key:admin666 iv:9999admi
autoDecode

成功解密

【第六关】明文加签
依旧抓包

可以看到有两个参数不清楚是啥,分别是nonce,signature,还有个时间戳,分析下js看看,依旧是js中下断点,发包

function sendDataWithNonce(url) {const username = document.getElementById("username").value;const password = document.getElementById("password").value;const nonce = Math.random().toString(36).substring(2);const timestamp = Math.floor(Date.now() / 1000);const secretKey = "be56e057f20f883e";const dataToSign = username + password + nonce + timestamp;const signature = CryptoJS.HmacSHA256(dataToSign, secretKey).toString(CryptoJS.enc.Hex);
nonce:由0-9 a-z生成的10位随机数
dataToSign:username + password + nonce + timestamp
signature:由dataToSign经SHA256加密生成,secretKey为固定值be56e057f20f883e
SHA256在autoDecoer中没有,尝试自写发包器,其中nonce可以随机生成也可以固定
import requests
import time
import hashlib
import hmacdef generate_signature(username, password, nonce, timestamp, secret_key):data_to_sign = username + password + nonce + str(timestamp)h = hmac.new(secret_key.encode('utf-8'), digestmod=hashlib.sha256)h.update(data_to_sign.encode('utf-8'))return h.hexdigest()url = "http://82.156.57.228:43899/encrypt/signdata.php"
username = "admin"
password = "123456"
nonce = "dq7kos6hzy"
secret_key = "be56e057f20f883e"while True:timestamp = int(time.time())signature = generate_signature(username, password, nonce, timestamp, secret_key)headers = {"Host": "82.156.57.228:43899","Content-Length": "163","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36","Content-Type": "application/json","Accept": "*/*","Origin": "http://82.156.57.228:43899","Referer": "http://82.156.57.228:43899/easy.php","Accept-Encoding": "gzip, deflate","Accept-Language": "zh-CN,zh;q=0.9","Cookie": "PHPSESSID=q3nlpgst4h9kpdiklq2rcbrnc1","Connection": "close"}data = {"username": username,"password": password,"nonce": nonce,"timestamp": timestamp,"signature": signature}response = requests.post(url, json=data, headers=headers)print(response.status_code)print(response.text)time.sleep(1) # 发包间隔

【第七关】加签key在服务端
依旧抓包,发送了俩数据包


通过第一个数据包获取signature,第二个数据包发包时加上这个,达到加签key在服务端的效果
emmm测试了下,如果要做密码爆破操作的话,需要发第一个包
获取对应的signature值,丢到第二个包中,依旧是自写脚本即可,不难,这里不演示了。
【第八关】禁止重放
还是抓包 账号密码还是明文的,多次重放发现返回No Repeater

其中加密参数为random,分析js看看
依旧是断点,查看

function generateRequestData() {const username = document.getElementById("username").value;const password = document.getElementById("password").value;const timestamp = Date.now();const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi
NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM
DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb
ocDbsNeCwNpRxwjIdQIDAQAB
-----END PUBLIC KEY-----`;function rsaEncrypt(data, publicKey) {const jsEncrypt = new JSEncrypt(); jsEncrypt.setPublicKey(publicKey);const encrypted = jsEncrypt.encrypt(data.toString());if (!encrypted) {throw new Error("RSA encryption failed.");}return encrypted;}// Encrypt the timestamplet encryptedTimestamp;try {encryptedTimestamp = rsaEncrypt(timestamp, publicKey);} catch (error) {console.error("Encryption error:", error);return null;}const dataToSend = {username: username,password: password,random: encryptedTimestamp // Replace timestamp with encrypted version};return dataToSend;
}function sendLoginRequest(url) {const dataToSend = generateRequestData();unction sendLoginRequest(url) {const dataToSend = generateRequestData();function generateRequestData() {const username = document.getElementById("username").value;const password = document.getElementById("password").value;const timestamp = Date.now();
现在是要寻找random参数怎么来的,根据上面js可知是通过encryptedTimestamp来的,encryptedTimestamp是通过时间戳经过RSA加密来的
依旧写一个发包器来实现
import requests
import json
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from base64 import b64encode, b64decode
import timedef rsa_encrypt(data, public_key):"""RSA加密,Base64格式"""key = RSA.import_key(public_key)cipher = PKCS1_v1_5.new(key)encrypted_data = cipher.encrypt(data.encode('utf-8'))return b64encode(encrypted_data).decode('utf-8')def generate_request_data():"""生成random字段"""username = "admin"password = "123456"timestamp = str(int(round(time.time() * 1000))) # 时间戳print(timestamp)public_key = """-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi
NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM
DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb
ocDbsNeCwNpRxwjIdQIDAQAB\n-----END PUBLIC KEY-----"""encrypted_timestamp = rsa_encrypt(timestamp, public_key)data_to_send = {"username": username,"password": password,"random": encrypted_timestamp}print(data_to_send)return data_to_senddef send_request():url = "http://82.156.57.228:43899/encrypt/norepeater.php"headers = {"Host": "82.156.57.228:43899","Content-Length": "224","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36","Content-Type": "application/json; charset=utf-8","Accept": "*/*","Origin": "http://82.156.57.228:43899","Referer": "http://82.156.57.228:43899/easy.php","Accept-Encoding": "gzip, deflate","Accept-Language": "zh-CN,zh;q=0.9","Connection": "close"}data = generate_request_data()response = requests.post(url, headers=headers, data=json.dumps(data))print(response.text)if __name__ == "__main__":while True: send_request()time.sleep(5)相关文章:
前端加解密对抗encrypt-labs
前言 项目地址:https://github.com/SwagXz/encrypt-labs 作者:SwagXz 现在日子越来越不好过了,无论攻防、企业src还是渗透项目,总能看到大量的存在加密的网站,XZ师傅的前端加密靶场还是很值得做一做的,环…...
Android Notification 问题:Invalid notification (no valid small icon)
问题描述与处理策略 1、问题描述 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.my.notifications/com.my.notifications.MainActivity}: java.lang.IllegalArgumentException: Invalid notification (no valid small icon): Notification(chan…...
Python爬虫教程——7个爬虫小案例(附源码)_爬虫实例
本文介绍了7个Python爬虫小案例,包括爬取豆瓣电影Top250、猫眼电影Top100、全国高校名单、中国天气网、当当网图书、糗事百科段子和新浪微博信息,帮助读者理解并实践Python爬虫基础知识。 包含编程资料、学习路线图、源代码、软件安装包等!【…...
Log4j2的Policies详解、SizeBasedTriggeringPolicy、TimeBasedTriggeringPolicy
文章目录 一、Policies二、SizeBasedTriggeringPolicy:基于文件大小的滚动策略2.1、文件达到指定大小就归档 三、TimeBasedTriggeringPolicy:基于时间间隔的滚动策略3.1、验证秒钟归档场景3.2、验证分钟场景3.3、验证小时场景 四、多策略组合使用五、扩展知识5.1、S…...
ES中查询中参数的解析
目录 query中参数match参数match_allmatch:匹配指定参数match_phrase query中其他的参数query_stringprefix前缀查询:wildcard通配符查询:range范围查询:fuzzy 查询: 组合查询bool参数mustmust_notshould条件 其他参数 query中参数 词条查询term:它仅匹配在给定字段…...
学习笔记:使用 pandas 和 Seaborn 绘制柱状图
学习笔记:使用 pandas 和 Seaborn 绘制柱状图 前言 今天在使用 pandas 对数据进行处理并在 Python 中绘制可视化图表时,遇到了一些关于字体设置和 Seaborn 主题覆盖的小问题。这里将学习到的方法和注意事项做个总结,以便之后的项目中可以快…...
【每日学点鸿蒙知识】placement设置top、组件携带自定义参数、主动隐藏输入框、Web设置字体、对话框设置全屏宽
1、popup组件placement设置top没有生效? 可以用offset属性将popup往下边偏移一下 来规避 2、组件携带自定义参数的接口是哪个? 参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-…...
后端开发-Maven
环境说明: windows系统:11版本 idea版本:2023.3.2 Maven 介绍 Apache Maven 是一个 Java 项目的构建管理和理解工具。Maven 使用一个项目对象模型(POM),通过一组构建规则和约定来管理项目的构建…...
自动化办公-合并多个excel
在日常的办公自动化工作中,尤其是处理大量数据时,合并多个 Excel 表格是一个常见且繁琐的任务。幸运的是,借助 Python 语言中的强大库,我们可以轻松地自动化这个过程。本文将带你了解如何使用 Python 来合并多个 Excel 表格&#…...
mavlink移植到单片机stm32f103c8t6,实现接收和发送数据
前言: 好久没更新博客了,这两个月真的是异常的忙,白天要忙着公司里的事,晚上还要忙着修改小论文,一点自己的时间都没有了,不过确确实实是学到了很多东西,对无人机的技术研究也更深了一些。不过好…...
小程序基础 —— 08 文件和目录结构
文件和目录结构 一个完整的小程序项目由两部分组成:主体文件、页面文件: 主体文件:全局文件,能够作用于整个小程序,影响小程序的每个页面,主体文件必须放到项目的根目录下; 主体文件由三部分组…...
FIR数字滤波器设计——窗函数设计法——滤波器的时域截断
与IIR数字滤波器的设计类似,设计FIR数字滤波器也需要事先给出理想滤波器频率响应 H ideal ( e j ω ) H_{\text{ideal}}(e^{j\omega}) Hideal(ejω),用实际的频率响应 H ( e j ω ) H(e^{j\omega}) H(ejω)去逼近 H ideal ( e j ω ) H_{\text{ideal}}…...
MySQLOCP考试过了,题库很稳,经验分享。
前几天,本人参加了Oracle认证 MySQLOCP工程师认证考试 ,先说下考这个证书的初衷: 1、首先本人是从事数据库运维的,今年开始单位逐步要求DBA持证上岗。 2、本人的工作是涉及数据库维护,对这块的内容比较熟悉ÿ…...
WPF 绘制过顶点的圆滑曲线 (样条,贝塞尔)
在一个WPF项目中要用到样条曲线,必须过顶点,圆滑后还不能太走样,捣鼓一番,发现里面颇有玄机,于是把我多方抄来改造的方法发出来,方便新手: 如上图,看代码吧: ----------…...
Kafka 幂等性与事务
文章目录 幂等性实现机制配置使用局限性 事务使用场景配置使用实现机制事务过程事务初始化事务开始事务提交事务取消事务消费 幂等性 Producer 无论向 Broker 发送多少次重复的数据,Broker 端只会持久化一条,保证数据不丢失且不重复。 实现机制 通过引…...
day2 Linux操作系统指令
思维导图 在家目录下创建目录文件,dir 1、dir下创建dir1和dir2 2、把当前目录下的所有文件拷贝到dir1中, 3、把当前目录下的所有脚本文件拷贝到dir2中 4、把dir2打包并压缩为dir2.tar.xz 5、再把dir2.tar.xz移动到dir1中 6、解压dir1中的压缩包 7、使用…...
AI一周重要会议和活动概览
一、小模型的曙光和机会之思辨高峰论坛 会议介绍:小模型的曙光和机会之思辨”高峰论坛暨第32期CSIG图像图形学科前沿讲习班于2025年1月3—4日在杭州举办,会议由中国图象图形学学会主办,中国图象图形学学会前沿科技论坛委员会承办。本次论坛设…...
重启ubuntu服务器,如何让springboot服务自动运行
文章目录 1. 使用 systemd 服务步骤: 2. 使用 cron 的 reboot 任务步骤: 3. 使用 init.d 脚本(适用于较旧版本)步骤: 推荐方案 为了确保在重启Ubuntu服务器后,让springboot的服务test.jar象 nohup java -ja…...
python系列教程237——启动扩展功能
朋友们,如需转载请标明出处:https://blog.csdn.net/jiangjunshow 声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享…...
U盘格式化工具合集:6个免费的U盘格式化工具
在日常使用中,U盘可能会因为文件系统不兼容、数据损坏或使用需求发生改变而需要进行格式化。一个合适的格式化工具不仅可以清理存储空间,还能解决部分存储问题。本文为大家精选了6款免费的U盘格式化工具,并详细介绍它们的功能、使用方法、优缺…...
Zabbix监控Docker化部署避坑指南:从镜像版本选择到安全加固的完整配置
Zabbix监控Docker化部署避坑指南:从镜像版本选择到安全加固的完整配置 在容器化技术席卷运维领域的今天,将Zabbix监控系统部署在Docker环境中已成为主流选择。但看似简单的docker-compose up -d背后,隐藏着无数可能让运维工程师深夜加班的&qu…...
3个实用技巧:Anemone3DS让3DS玩家实现主题个性化定制
3个实用技巧:Anemone3DS让3DS玩家实现主题个性化定制 【免费下载链接】Anemone3DS A theme and boot splash manager for the Nintendo 3DS console 项目地址: https://gitcode.com/gh_mirrors/an/Anemone3DS Anemone3DS是一款专为任天堂3DS掌机设计的主题和…...
佣金自动算、订单自动记,这才叫好系统
做推客、做分销、做私域小店,最磨人的从来不是拉新和卖货,而是没完没了的记账、对账、算佣金。人工统计订单、Excel 算佣金、靠截图核对业绩,不仅慢、容易错,还特别消耗信任。真正能让商家省心、让推客放心的好系统,标…...
网络基础回顾:DNS、IP封锁与HTTP/S协议关键点
网络基础回顾:DNS、IP封锁与HTTP/S协议关键点 昨天有个读者在后台问我:“为什么改了Hosts文件还是打不开ZLibrary?明明Ping得通啊。” 这个问题让我想起刚入行时踩过的坑——你以为网络通了,其实只是你以为。今天我们就从这个问题…...
保姆级避坑指南:用Anaconda和Xinference在Windows上部署LangChain-Chatchat(附解决httpx报错)
Windows系统下LangChain-Chatchat本地化部署全流程避坑手册 最近在帮几个朋友部署LangChain-Chatchat时,发现即便是按照官方文档操作,Windows环境下依然会遇到各种"坑"。特别是当Anaconda、Xinference和LangChain-Chatchat这几个组件混在一起…...
MATLAB报错解析:深入理解eval与struct类型冲突的根源及修复方法
1. 从报错现象看MATLAB底层机制 第一次遇到"错误使用eval,未定义与struct类型的输入参数相对应的函数workspacefunc"这个报错时,我盯着红色报错信息愣了半天。作为用了MATLAB七八年的老用户,这种底层函数报错还真不多见。后来在论坛…...
Pixel Epic智识终端部署教程:Streamlit CSS注入与16-bit视觉系统适配
Pixel Epic智识终端部署教程:Streamlit CSS注入与16-bit视觉系统适配 1. 项目介绍与核心价值 Pixel Epic智识终端是一款将专业研究报告生成与复古游戏美学完美融合的创新工具。它基于AgentCPM-Report大模型构建,通过独特的16-bit像素风格界面ÿ…...
FLUX.1-dev像素生成器应用场景:复古计算器UI、像素风仪表盘可视化设计
FLUX.1-dev像素生成器应用场景:复古计算器UI、像素风仪表盘可视化设计 1. 像素艺术生成的新纪元 像素幻梦(Pixel Dream Workshop)是基于FLUX.1-dev扩散模型构建的专业像素艺术生成工具。与传统像素画工具不同,它采用16-bit现代明…...
效率提升秘籍:用快马平台AI快速生成并对比多种代码性能优化方案
今天想和大家分享一个前端性能优化的实战案例——如何快速对比不同优化方案对大数据列表渲染性能的影响。最近在做一个需要展示上万条数据的项目时,遇到了明显的卡顿问题,正好用InsCode(快马)平台尝试了多种优化方案,效果非常显著。 问题背景…...
Python MCP模板不是万能的!但这个经17家金融机构验证的增强版,已将接入耗时压缩至行业均值的1/5.8
第一章:Python MCP 服务器开发模板如何实现快速接入Python MCP(Model Control Protocol)服务器开发模板为构建符合 MCP 规范的智能体控制后端提供了开箱即用的骨架结构,显著降低协议适配与服务部署门槛。该模板基于 FastAPI 构建&…...
