前端加解密靶场思路分享
前言
平常在渗透测试的过程中,对于加密传输的账密,无法爆破也不是弱密码的情况下,你是否也会束手无策,下面打一个前辈的前端加解密靶场,通过简单的js分析和抓包,让你有机会登入系统。
这里为了方便大家了解原理,对于比较难的一块(混淆)我们就先略过,直接使用作者推荐的easy.php(进去你会发现全是人眼看得懂的js代码,看下面你就知道了)
非easy
easy
-
这里要补充的一点就是,学会调试代码很重要哦,这关乎到我们怎么定位到登录在的函数.
-
在谷歌浏览器F12以后,点到开发者工具区域,然后F8是开始调试模式,F9,F10,F11不同的功能(这个自己打开F12看一下就知道了)
-
(谷歌浏览器的调试区域是下面这张图)
第一关 AES固定key
第一关剖析思路
-
首先这关是使用对称加密,有固定的key泄露的情况
-
在这里我们能够通过抓包以及分析js,会发现数据是用AES加密的
-
还能在里面发现加密的模式(CBC)和密钥(有用来增加随机性的iv,和用来数学置换的key)。
那我们有了这些信息,要怎么绕过系统登录呢?就有下面两个思路
1.首先对于传输的数据,对方的后端本应该是先经过解密然后去数据库中进行比对的,但是我们直接明文传输过去,由于缺乏校验,对方就有可能不会去数据库校验,直接判定成功。
-
所以像上面这种已知加密方式能够解密成明文的,我们就可以将发出去的包解密成明文,直接传输,看他的回显就知道能否通过这种方式绕过了。
2.知道了加密方式,明文都出来了就用爆破呗(autodecoder或者自己写脚本)
我们先抓包
-
可以看到被加密的数据,我们直接去js查
查看js
-
能够看到是用AES加密的,key也给了,模式也知道,就可以改包进行明文发送啦
工具解密
-
这里是用的靶场建立者推荐的bp解密插件autodecoder
解密改包进系统
第二关 AES服务端获取Key
第二关剖析思路
-
这里和第一关近乎一致,不一样的就是你的key值是服务端发过来的。(AES服务端获取Key)
-
这关会获取到两个数据包,一个是服务端返回的key和iv包,(你会发现这个key和iv基本是固定的),另一个是登录数据包。理解上面第一关的自然知道咋做咯,不做重复工作了~
第三关 RSA加密
第三关剖析思路
-
这关和前两关有点不一样,使用的是非对称加密(RSA),我们都知道非对称加密和对称加密的区别就是使用一对钥匙,公钥加密,私钥解密。
-
在这关里面,你会看到前端js部分泄露了公钥(私钥没人那么蠢会泄露把笑死)。
-
我们这里破解系统的新思路就是,使用公钥对已经加密过的密文再进行加密~
F12发现公钥以及RSA加密
通过分析打断点能够看到在被RSA加密之前最后的样子
-
断点直接在73旁边点一下就好了,可以看到上面有一行username啥的,去掉就是我们要的
用工具和正则对每一次请求的数据都进行一次加密
最后爆破
第四关 AES+Rsa加密
第四关剖析思路
-
这关开始上强度了,基本意思抓个包就能看懂,就是第一关和第三关结合起来,把RSA加密和AES加密结合起来 -
我们要做的就是看一下AES有没有固定的key,没有固定的key要怎么解密这样
先抓包看下把
调试看下,可以发现AES的key和iv是随机生成的
RSA使用的公钥还是之前的
-
滤清思路:人家是先使用随机的key,用AES加密,然后再用RSA的公钥裹上一层加密。
-
那不用说后端肯定就是私钥解密,再用相同的随机key解密AES
-
这里要强调的一点是,既然是随机的key,固定也是随机的一种
意思就说后端肯定是拿我们发过去的key来解密的,随机数可以是任意值。这里我们直接覆盖js,把它变成定式就好了
这里直接改成我们第一关的~
-
替换以后记得ctrl+s
抓包
我这个key和iv试验了,都是不变的值
爆破即可(RSA还是和之前一样的配置)
第五关 Aes规律Key
第五关剖析思路
-
这一关和第一关差不多,加密值同样是固定的,只不过说是有固定的规律可循,找到规律就可以写py脚本爆破啦(虽然我们已经知道密码就是了)
抓包可以看到只有密码被加密
抓断点分析只对密码进行AES加密
-
可以看到规律,key是截取用户名的8个字符,没有8个字符就用6补全,iv则是9999加username的前四位。 -
这里考的就是AES的一种特定情况,具有一定规律,但是万变不离其宗,就像是y=kx一样,我们只要写个脚本改个k就好了
第六关 明文加签
第六关剖析思路
这一关就是加了一些额外的签名,我们只要看一下这个签名是不是固定的,有什么规律,照样爆
抓包
-
我们可以通过抓包看到多了个随机数nonce,一个时间戳,和一个签名,接下来就是调试找规律
调试
-
可以看到是先数学产生一个随机数(先转换为一个 36 进制的字符串,再截取从索引 2 开始到字符串末尾的部分)
-
签名就是先使用随机过的值,加上时间戳等等用密钥和sha256算法算出一个比较难破解的值
-
它首先是个随机值,还要加上一直变换的时间,这么繁杂的加密过程要怎么办呢。
-
其实很简单,从上面的第四关也知道,你前端再怎么随机,后端调用的时候还是你前端的值
-
固定也是随机的一种情况,所以我们只要随便写一个数就行
-
至于后面的签名,也就是很好解决的了,我们只要在py调用一个类似的函数,发包爆破也就可以了,这里就借用一下前辈的脚本咯
import requests
import time
import hashlib
import hmac
defgenerate_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"
whileTrue:
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是在后端生成的,理论上来说我们这关是不应该知道它后端的校验是什么样子的。。但是我们都做了上面那一关了。。加上题目猜也能猜到。
调试
抓包会发现有两个包
-
第一个是返回的签名
-
第二个是根据签名再发送
-
有了第六关的基础这也不难了,py写一个脚本接收第一个返回的包的内容再按照第六关的操作就可以了,这里不再演示
第八关 禁止重放
第八关剖析思路
-
这关虽然说名字是禁止重放,表现的也确实是,那我们就真的不能重放了嘛(doge),审计一下源码就知道原因咯~
-
看看源码就是把时间戳进行RSA加密了,等我们重放的时候就已经结束嘞,依旧写一个py脚本实现(别看我,偷的,自己懒得写脚本)
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 time
defrsa_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')
defgenerate_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
ocDbsNeCwNpRxwjIdQIDAQABn-----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_send
defsend_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__":
whileTrue:
send_request()
time.sleep(5)
最后分享一个渗透系统
-
我用夸克网盘分享了「你想要的都在这」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。 链接:https://pan.quark.cn/s/905d88fecaf5 提取码:kjxd
原文始发于微信公众号(泷羽sec-KI安全):前端加解密靶场思路分享
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论