
新闻动态
文章首发于先知社区:https://xz.aliyun.com/t/16919
项目地址: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-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujviNH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlMDSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3CbocDbsNeCwNpRxwjIdQIDAQAB-----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-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujviNH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlMDSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3CbocDbsNeCwNpRxwjIdQIDAQAB-----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:admin666iv:9999admiautoDecode图片
成功解密图片
【第六关】明文加签依旧抓包
图片
可以看到有两个参数不清楚是啥,分别是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 requestsimport timeimport hashlibimport 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-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujviNH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlMDSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3CbocDbsNeCwNpRxwjIdQIDAQAB-----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 timestamp let 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(); functiongenerateRequestData() { const username = document.getElementById('username').value; const password = document.getElementById('password').value; const timestamp = Date.now();
现在是要寻找random参数怎么来的,根据上面js可知是通过encryptedTimestamp来的,encryptedTimestamp是通过时间戳经过RSA加密来的
依旧写一个发包器来实现
import requestsimport jsonfrom Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_v1_5from Crypto.Cipher import AESfrom Crypto.Util.Padding import padfrom base64 import b64encode, b64decodeimport 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-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujviNH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlMDSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3CbocDbsNeCwNpRxwjIdQIDAQAB\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) 本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报。上一篇:新闻1+1丨应对外部冲击 中央政治局会议释放哪些信号?
下一篇:没有了
Powered by 澳门2023历史开奖记录查询表最新 @2013-2022 RSS地图 HTML地图