[JS reverse hundreds of examples] HN logs into a service network in reverse, and the verification code is null and void

statement

All contents in this article are for learning and communication only. The packet capturing content, sensitive website and data interface have been desensitized. It is strictly prohibited to use them for commercial and illegal purposes, otherwise all the consequences have nothing to do with the author. If there is infringement, please contact me and delete them immediately!

Reverse target

  • Target: login interface of a government service network
  • Home page: aHR0cHM6Ly9sb2dpbi5obnp3ZncuZ292LmNuL3RhY3MtdWMvbG9naW4vaW5kZXg=
  • Interface: aHR0cHM6Ly9sb2dpbi5obnp3ZncuZ292LmNuL3RhY3MtdWMvbmF0dXJhbE1hbi9sb2dpbk5v
  • Reverse parameters:

Form Data: loginNo,loginPwd,code,requestUUID

Request Headers: token

Packet capture analysis

This reverse target comes from the help of a fan:

Casually enter the account password and click log in. After capturing the packet, it is found that the Request Headers of the interface have an encryption parameter token. loginNo, loginPwd, code and requestUUID in the Form Data are encrypted. loginNo and loginPwd should be the user name and password. Since the sliding verification code is required before logging in, it can be guessed that the other two parameters are related to the verification code, However, only from the point of view of packet capture, the other two parameters are similar to the format of uuid, not like the parameters of verification code.

In addition, it can be noted that before logging in, there are two csrfSave and one verCode requests. If the normal request is successful, a JSON will be returned with a data parameter, which should be used later.

Parameter inversion

Form Data

First look at the Form Data and search for any parameter, such as loginNo, which is easy in login JS. The user name and password are encrypted by the encrypt function. The value of backUrl is obtained from the data of the key value pair stored in the browser by using the localStorage attribute. If it is empty, it will not be affected.

Follow up encrypt and you can see that JSEncrypt, standard RSA encryption, is used:

Take another look at loginCode. Directly search this value, and you can see that it is returned by the request for verCode:

Then take a look at requestUUID. Its value is a UUID. Search directly in the current file (login.js). You can see that there is an uploadUUID() method in the definition, which sets the UUID value. In the method, a post request is sent to an uploadIdentifier interface:

Note here that if you directly search UUID globally, you can also search in common A method is found in JS. After testing, it can also be requested to pass by directly using this method to generate a UUID. This website may not be rigorous and will not strictly detect this value.

Request Headers

After the Form Data is solved, let's look at the token parameter in the Request Headers. Since it exists in the request header, we can find the place where it is generated through Hook:

(function () {
    var org = window.XMLHttpRequest.prototype.setRequestHeader;
    window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
        if (key == 'token') {
            debugger;
        }
        return org.apply(this, arguments);
    };
})();

Here, we can also directly search keywords such as token and setRequestHeader, which can be easily found in common JS. When we click login, there will be a csrfSave request. The returned data value is the token of the login request header after being encrypted by the encrypt method.

This token parameter is used in many requests. The generation method is the same. It is obtained by encrypting the data returned by the csrfSave request with RSA:

In addition, it should be noted that all the above cookies related to network requests need a SESSION value, which can be obtained on the first visit page:

Login process

Here, let's sort out the login process:

  1. Visit the homepage to get the SESSION value in the Cookie;
  2. Access csrfSave, get a data value, get a token through RSA encryption, and carry the token to access uploadIdentifier to get uuid;
  3. Access csrfSave, get a data value, get the token through RSA encryption, carry the token to access verCode, and get the code;
  4. Access csrfSave, get a data value, get the token through RSA encryption, carry the token, uuid, code and the encrypted account password, and access loginNo to log in.

In step 2, you can also directly generate a uuid in Python or JS. The website verification is not strict, or you can pass. In addition, you can see that the slider is false. You can log in without the slider through the code.

Complete code

GitHub pays attention to brother K crawler and continues to share crawler related codes! Welcome, star! https://github.com/kgepachong/

The following only demonstrates part of the key code and cannot be run directly! Full code warehouse address: https://github.com/kgepachong/crawler/

JavaScript encryption code

/* ==================================
# @Time    : 2022-01-11
# @Author  : WeChat official account: K brother crawler
# @FileName: encrypt.js
# @Software: PyCharm
# ================================== */

JSEncrypt = require("jsencrypt")

function encrypt(pwd){
	var key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgDq4OqxuEisnk2F0EJFmw4xKa5IrcqEYHvqxPs2CHEg2kolhfWA2SjNuGAHxyDDE5MLtOvzuXjBx/5YJtc9zj2xR/0moesS+Vi/xtG1tkVaTCba+TV+Y5C61iyr3FGqr+KOD4/XECu0Xky1W9ZmmaFADmZi7+6gO9wjgVpU9aLcBcw/loHOeJrCqjp7pA98hRJRY+MML8MK15mnC4ebooOva+mJlstW6t/1lghR8WNV8cocxgcHHuXBxgns2MlACQbSdJ8c6Z3RQeRZBzyjfey6JCCfbEKouVrWIUuPphBL3OANfgp0B+QG31bapvePTfXU48TYK0M5kE+8LgbbWQIDAQAB";
	var encrypt = new JSEncrypt();
    encrypt.setPublicKey(key);
    var encrypted = encrypt.encrypt(pwd);
    return encrypted;
}

// Test sample
// console.log(encrypt("15555555555"))

Python login code

# ==================================
# @Time    : 2022-01-11
# @Author: WeChat official account: K brother crawler
# @FileName: hnzww_login.py
# @Software: PyCharm
# ==================================


import execjs
import requests


cookies = {}
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"

with open("encrypt.js", encoding="utf-8") as f:
    js = execjs.compile(f.read())


def csrf_save():
    url = "Desensitization, complete code attention GitHub: https://github.com/kgepachong/crawler"
    headers = {"User-Agent": UA}
    response = requests.post(url=url, headers=headers, cookies=cookies).json()
    data = response["data"]
    return data


def get_session():
    url = "Desensitization, complete code attention GitHub: https://github.com/kgepachong/crawler"
    headers = {"User-Agent": UA}
    response = requests.get(url=url, headers=headers)
    cookies.update(response.cookies.get_dict())


def get_uuid():
    url = "Desensitization, complete code attention GitHub: https://github.com/kgepachong/crawler"
    headers = {
        "User-Agent": UA,
        "token": js.call("encrypt", csrf_save())
    }
    response = requests.post(url=url, headers=headers, cookies=cookies).json()
    uuid = response["data"]
    return uuid


def ver_code():
    url = "Desensitization, complete code attention GitHub: https://github.com/kgepachong/crawler"
    headers = {
        "User-Agent": UA,
        "token": js.call("encrypt", csrf_save())
    }
    response = requests.post(url=url, headers=headers, cookies=cookies).json()
    data = response["data"]
    return data


def login(phone, pwd, code, uuid):
    url = "Desensitization, complete code attention GitHub: https://github.com/kgepachong/crawler"
    headers = {
        "User-Agent": UA,
        "token": js.call("encrypt", csrf_save())
    }
    data = {
        "backUrl": "",
        "loginNo": js.call("encrypt", phone),
        "loginPwd": js.call("encrypt", pwd),
        "code": code,
        "requestUUID": uuid,
        "guoBanAuthCode": ""
    }
    response = requests.post(url=url, headers=headers, cookies=cookies, data=data)
    print(response.json())


def main():
    phone = input("Please enter account number:")
    pwd = input("Please input a password:")
    get_session()
    uuid = get_uuid()
    code = ver_code()
    login(phone, pwd, code, uuid)


if __name__ == '__main__':
    main()

Keywords: Python Data Mining

Added by ssruprai on Wed, 19 Jan 2022 10:36:57 +0200