首先输入随机账号,密码为123456,进行尝试:
共有5个参数,email_or_phone,password,type,redirectTo,_token。除了redirectTo,其余均为加密。
首先看password参数。
直接搜索字符串:
共有34个匹配结果。
下个XHR断点看看。
看一下调用栈:
可以看到在dispatch时,并没有password参数的信息,但是能看到此时的type为明文字符串submit。
查看下一个调用栈,到匿名这里,obj里包含了登录请求中的所有参数:
接下来就重点关注login.html中的obj。
直接搜索obj,依次往上找:
代码如下:
var obj = {
'email_or_phone': aes($(".formAccount .email_or_phone").val()),
'password': aes($(".formAccount .password").val()),
'type': aes('account'),
'redirectTo': 'https://www.dns.com/dashboard',
'_token': _token
}
首先是通过$(…)选择器选中表单元素,再通过aes进行加密,加密的关键点应该就在aes()中。
通过console.log()确认一下传入的参数是不是输入的明文值:
一致。
其实这里在通过XHR定位到大概的位置之后,直接搜索password也能很快找到:
或者搜索123456等可能的密钥:
只有两个结果,并且直接跟到了aes函数内部。
将js代码改为python实现,代码如下:
from Crypto.Cipher import AES
import base64
def pad_zero_padding(data, block_size):
padding_len = block_size - (len(data) % block_size)
return data + (b' ' * padding_len)
def aes(val):
key = b'1234567890abcDEF'
iv = b'1234567890abcDEF'
# Create AES cipher with CBC mode
cipher = AES.new(key, AES.MODE_CBC, iv)
# Pad the input value with zero padding
padded_val = pad_zero_padding(val.encode('utf-8'), AES.block_size)
# Encrypt the padded value
encrypted_bytes = cipher.encrypt(padded_val)
# Encode the encrypted bytes to base64 to get a string representation
enc = base64.b64encode(encrypted_bytes).decode('utf-8')
print(val,enc)
aes("13888888888")
aes("123456")
aes("account")
需要注意,JavaScript代码使用的是ZeroPadding,而Python代码使用的是iso7816填充,因此需要在python中也利用zeropadding的方式进行加密。
加密结果与请求中的payload一致。
最后还剩下_token,直接全局搜索,发现在login.html中是写死的:
原文始发于微信公众号(Crush Sec):js逆向系列08-DNS.com