起因
最近遇到了kubesphere,本想爆破一波用户密码,但是密码却是加密的,效果如下所示:
很重要,于是我去网上搜索相关的内容,却没有一丁点记录,遂决定自己看看,将前端JS加密代码改写为python代码。完整的python代码见下文。过程很简单,就当看一乐。
经过
第一步 寻找加密代码
在一番搜索过后(普遍都是搜索“encrypt”关键字),在JS代码中找到了加密函数,代码如下:
function x(e, t) {
return function(e, t) {
t.length > e.length && (e += t.slice(0, t.length - e.length));
for (var n = [], r = [], o = 0, a = e.length; o < a; o++) {
var i = t.length > o ? t.charCodeAt(o) : 64
, l = e.charCodeAt(o) + i;
r.push(l % 2 == 0 ? "0" : "1"),
n.push(String.fromCharCode(Math.floor(l / 2)))
}
return "".concat(b.Base64.encode(r.join("")), "@").concat(n.join(""))
}(e, b.Base64.encode(t))
}
第二步 阅读加密代码
e为加密key,key值的由来是在尝试从全局对象中获取一个名为"config.encryptKey"的属性值,如果该属性不存在,则使用默认值"kubesphere"。
ar a = (0,y.default)(globals, "config.encryptKey", "kubesphere");
t为密码,密码的由来是用户输入,下面写作pwd。
t.length > e.length && (e += t.slice(0, t.length - e.length));
这段代码的意思是,如果pwd的长度大于key的长度,则将pwd中与key长度相匹配的部分追加到key的末尾,确保两者的长度相等。
for (var n = [], r = [], o = 0, a = e.length; o < a; o++) {
var i = t.length > o ? t.charCodeAt(o) : 64
, l = e.charCodeAt(o) + i;
r.push(l % 2 == 0 ? "0" : "1"),
n.push(String.fromCharCode(Math.floor(l / 2)))
}
n=[]
和 r=[]
: 初始化两个空数组n
和r
。
o = 0
: 初始化计数器o
为0。
a = e.length
: 定义变量a
为key的长度。
var i = t.length > o ? t.charCodeAt(o) : 64: 这是一个三元操作符。如果pwd的长度大于当前的o,则取pwd的第o个字符的ASCII码值,否则取64(ASCII码中空格的值)。
l = e.charCodeAt(o) + i;: 获取字符串key的第o个字符的ASCII码值,并与之前得到的值i相加。
r.push(l % 2 == 0 ? "0" : "1"): 将l除以2的余数为0则将"0"添加到数组r中,否则添加"1"。
n.push(String.fromCharCode(Math.floor(l / 2))): 将l除以2并向下取整,然后使用该值创建一个字符并添加到数组n中。
return "".concat(b.Base64.encode(r.join("")), "@").concat(n.join(""))
最后就是使用join方法将数组r转为一个字符串1,然后将字符串进行base64编码,join方法将数组n转化为字符串2。最后将“base64编码后的字符串1”拼接“@”拼接“字符串2”得到的结果几位加密后的密码。
(e, b.Base64.encode(t))
还有最后一段代码的意思是,先将密码进行base64编码后再进入上面的加密代码。
第三步 重写加密代码
本人只会点皮毛python,重写后的加密代码如下:
def kubesphere_encrypt(key, password):
# 将传入的密码先进行一次base64编码,(e, b.Base64.encode(t))
password_b64 = base64.b64encode(password.encode()).decode()
key_len = len(key)
pwd_len = len(password_b64)
# 对应 t.length > e.length && (e += t.slice(0, t.length - e.length));
if pwd_len > key_len:
key = key + password_b64[0:pwd_len - key_len]
"""对应
for (var n = [], r = [], o = 0, a = e.length; o < a; o++) {
var i = t.length > o ? t.charCodeAt(o) : 64
, l = e.charCodeAt(o) + i;
r.push(l % 2 == 0 ? "0" : "1"),
n.push(String.fromCharCode(Math.floor(l / 2)))
}
"""
list_1 = []
list_2 = []
key2str_list = []
pwd2str_list = []
counter = 0
while counter < key_len:
if pwd_len > counter:
pwd2str = ord(password_b64[counter])
else:
pwd2str = 64
pwd2str_list.append(pwd2str)
key2str = ord(key[counter]) + pwd2str
key2str_list.append(key2str)
if key2str % 2 == 0:
list_2.append("0")
else:
list_2.append("1")
list_1.append(chr(math.floor(key2str / 2)))
counter = counter + 1
# 对应 return "".concat(b.Base64.encode(r.join("")), "@").concat(n.join(""))
return base64.b64encode("".join(list_2).encode()).decode() + "@" + "".join(list_1)
第四步 验证加密代码
key为“kubesphere”,pwd为“123456”。成功得到与前端JS一致的加密结果。
前端JS:MDExMTEwMTEwMQ==@dUo`Z^KYR
python:MDExMTEwMTEwMQ==@dUo`Z^KYR
完整的python代码如下:
import math
import base64
def kubesphere_encrypt(key, password):
# 将传入的密码先进行一次base64编码,(e, b.Base64.encode(t))
password_b64 = base64.b64encode(password.encode()).decode()
key_len = len(key)
pwd_len = len(password_b64)
# 对应 t.length > e.length && (e += t.slice(0, t.length - e.length));
if pwd_len > key_len:
key = key + password_b64[0:pwd_len - key_len]
"""对应
for (var n = [], r = [], o = 0, a = e.length; o < a; o++) {
var i = t.length > o ? t.charCodeAt(o) : 64
, l = e.charCodeAt(o) + i;
r.push(l % 2 == 0 ? "0" : "1"),
n.push(String.fromCharCode(Math.floor(l / 2)))
}
"""
list_1 = []
list_2 = []
key2str_list = []
pwd2str_list = []
counter = 0
while counter < key_len:
if pwd_len > counter:
pwd2str = ord(password_b64[counter])
else:
pwd2str = 64
pwd2str_list.append(pwd2str)
key2str = ord(key[counter]) + pwd2str
key2str_list.append(key2str)
if key2str % 2 == 0:
list_2.append("0")
else:
list_2.append("1")
list_1.append(chr(math.floor(key2str / 2)))
counter = counter + 1
# 对应 return "".concat(b.Base64.encode(r.join("")), "@").concat(n.join(""))
return base64.b64encode("".join(list_2).encode()).decode() + "@" + "".join(list_1)
if __name__ == '__main__':
k = "kubesphere"
p = "123456"
print(kubesphere_encrypt(key=k, password=p))
结果
加密脚本写出来了,赶紧呼哧呼哧掏出祖传大字典加密一波,就等着Burp一发入魂啦,结果尴了个大尬,刚开始就结束了,有登陆限制。
在下告辞!!!
原文始发于微信公众号(不够安全):kubesphere之登录密码加密分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论