JS reverse 5173 analysis encryption password

Limited space

Full content and source code: official account: ReverseCode, send punch

Grab bag

Login URL:

POST https://passport.5173.com/?returnUrl=http%3A//www.5173.com/

Parameters:

smsLogin: 0
userName: 15806204095
password: 6a771c7ecf7ebe2c3d4c0075cdb96ae5
mobileNo: 
smsCaptcha: 
category: 
passpod: 
__validationToken__: 1680e6a3947c43aea45d83e69b0d7291
__validationDna__: 

analysis

password

password has 32 bits, possibly md5

Search password, there are too many places, too lazy to see, give up.

Click the login button to confirm that the event is triggered, send a request, and search for invalid submit BTN results.

Search tnSubmit and add a breakpoint. When you click the login button, you are sure to break in this function. However, the request package on the Network panel has been sent, gg, and can not be intercepted https://passport.5173.com/?returnUrl=http%3a%2f%2fwww.5173.com%2f The point in time before the request is sent.

Try again. When encrypting password, we must get the value of the input box. If we get the element through id, we search #txtPass and mark breakpoints at all positions

Click login to see that the Network has blocked the validatesslide request and has not received the login request

When viewing the breakpoint, print o as aec712a02d8c835b92369e5d7e5494cf, and directly jump to return $[["ajax"]] to view a[["serialize"] () in the submitted data as "smslogin = 0 & username = 15806204095 & password = aec712a02d8c835b92369e5d7e5494cf & mobileno = & smcaptcha = & category = & password = & validationtoken = 31004cd552c94687ba27d1c72586f7 & validationdna =", The password is the o parameter printed before.

Since password=o, you only need to trace the source of this o parameter. Retroactively, it is passed in onsubmit: function(f, o) as the second parameter O. check the submitHandle of the calling method of the upper level through the call stack.

submitHandler returns a.onsubmit(a, c), where C is o=password in onsubmit: function(f, o). Since a.usingtpm | a.passwordhash is true, the C is obtained through a.getPassword(a.pkey).

After entering getPassword, this.ready & & this.activetpm & & this.usingtpm is false, and C = Hex in else must be entered_ md5(hex_md5(c).substr(8, 16) + a); Implement encryption.

(C = B ("#" + this. Passwordcontrolid. Val()) & & the assignment of this.passwordhash must be true, where the result of (C = B ("#" + this. Passwordcontrolid. Val()) is 123456, that is, the password we entered. Since the incoming a is 42m2gl, the encryption logic is sorted as c = hex_md5(hex_md5("123456").substr(8, 16) + "42m2gl")

So the question is, where did the incoming a come from? By searching 42m2gl, it turns out that every time the page is generated, the page will load the PasswordKey. Mutual verification and verification are realized through PasswordKey, SecurityToken and other keys.

__validationToken__

__ validationToken__ This field 6b16902a6b134dc9a2c333b965c9405f cannot be found in the request because the page has been refreshed and the packet is captured through fiddler https://passport.5173.com/?returnUrl=http%3a%2f%2fwww.5173.com%2f You can see the history. This parameter is passed in when the homepage is loaded

Crawler implementation

First request https://passport.5173.com/?returnUrl=http%3a%2f%2fwww.5173.com%2f

Get the value of PasswordKey and SecurityToken in the page, and pass the MD5 password hex twice_ MD5 (hex_md5 ("123456"). Substr (8, 16) + "42m2gl") gets the password encryption result and initiates the request.

def hex_md5(s):
    m = hashlib.md5()
    m.update(str(s).encode("utf-8"))
    return m.hexdigest()

headers = {
    'Host': 'passport.5173.com',
    'Origin': 'https://passport.5173.com',
    'Pragma': 'no-cache',
    'Referer': 'https://passport.5173.com/?returnUrl=http%3A//www.5173.com/',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest',
}
login_url = 'https://passport.5173.com/?returnUrl=http%3A//www.5173.com/'
html = requests.get(login_url).text
# print(html)
securityToken = re.findall('SecurityToken:"(.*?)",', html, re.M | re.S)[0]
passwordKey = re.findall('PasswordKey:"(.*?)",', html, re.M | re.S)[0]
print(passwordKey)
print(securityToken)


# Slider ' https://passport.5173.com/Sso/ValidateSlide?token={}'.format(securityToken)
# hex_md5(hex_md5("123456").substr(8, 16) + "42m2gl")
password = hex_md5(hex_md5("123456")[8:8 + 16] + passwordKey)
userName = '15806204096'

data = {
    'smsLogin': '0',
    'userName': userName,
    'password': password,
    'mobileNo': '',
    'smsCaptcha': '',
    'category': '',
    'passpod': '',
    '__validationToken__': securityToken,
    '__validationDna__': ''
}
r = requests.post(login_url, data, headers=headers)
print(r.text)

Although the password logic has been cracked, you still need to verify the verification code slider when logging in. Write it later when you have time...

This article is composed of blog one article multi posting platform OpenWrite release!

Added by phphead on Tue, 07 Dec 2021 15:43:40 +0200