statement
All the content in this article is for learning and communication only. The captured content, sensitive URLs, and data interfaces have been desensitized. Commercial and illegal uses are strictly prohibited. Otherwise, all consequences arising therefrom have nothing to do with the author. If there is any infringement , please contact me to delete immediately!
reverse goal
- Goal: Login interface of a government service network
- Home:
aHR0cHM6Ly9sb2dpbi5obnp3ZncuZ292LmNuL3RhY3MtdWMvbG9naW4vaW5kZXg=
- Interface:
aHR0cHM6Ly9sb2dpbi5obnp3ZncuZ292LmNuL3RhY3MtdWMvbmF0dXJhbE1hbi9sb2dpbk5v
Inverse parameters:
Form Data:loginNo、loginPwd、code、requestUUID
Request Headers:token
Packet capture analysis
This reverse goal comes from a fan's request for help:
Just enter the account password and click login. The Request Headers of the packet capture interface has an encrypted parameter token. The loginNo, loginPwd, code, and requestUUID in the Form Data are all encrypted. The loginNo and loginPwd should be the username and password. You need to go through the sliding verification code before, so you can guess that the other two parameters are related to the verification code, but only from the packet capture point of view, the other two parameters are similar to the uuid format, not very similar to the parameters of the verification code.
In addition, it can be noticed that there are two requests for csrfSave and one verCode before logging in. If the normal request is successful, a JSON will be returned with a data parameter, which should be used later.
Parametric inverse
Form Data
First look at Form Data, search for any parameter, such as loginNo, it is easy to find the encrypted place in login.js, the user name and password are encrypted by the encrypt function, and the value of backUrl is stored from the browser using the localStorage attribute. It is taken from the data of the key-value pair, and it is not affected if it is empty.
Following up on encrypt, you can see that JSEncrypt is used, the standard RSA encryption:
Look at the loginCode again, search for this value directly, and you can see that it is returned by the verCode request:
Then look at the requestUUID, its value is a UUID, search directly in the current file (login.js), you can see the definition, there is a uploadUUID()
method, which is to set the value of UUID, which is to an uploadIdentifier The interface sends a post request:
Note here that if you directly search for UUID globally, you can also search for a method in common.js. After testing, directly using this method to generate a uuid can also be requested to pass. This website may not be rigorous and will not strictly detect this value.
Request Headers
Form Data is solved, let's take a look at the token parameter in Request Headers. Since it exists in the request header, we can find the place where it is generated by 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 for keywords such as token and setRequestHeader, which are easy to find in common.js. When we click login, there will be a request for csrfSave, and the returned data value will be the login request header after being encrypted by the encrypt method. 's token.
This token parameter is used in many requests. The generation method is the same, which is obtained by RSA encryption of the data returned by the csrfSave request:
Another point to note is that for all the above related network requests, the cookie needs a SESSION value, which can be obtained on the first visit page:
Login process
Here is the process of logging in:
- Visit the homepage to get the SESSION value in the cookie;
- Access csrfSave, get a data value, get token after RSA encryption, access uploadIdentifier with token, and get uuid;
- Access csrfSave, get a data value, get a token through RSA encryption, access verCode with the token, and get the code;
- Access csrfSave, get a data value, get token after RSA encryption, carry token, uuid, code and encrypted account password, access loginNo to log in.
In the second step here, you can also directly generate a uuid with Python or JS. The website verification is not strict, and it can also pass. In addition, it can be seen that the slider is fake, and the code can ignore the slider to log in.
full code
GitHub pays attention to Brother K's crawler and continues to share crawler-related code! Welcome star! https://github.com/kgepachong/
following only demonstrates some key codes, which cannot be run directly! full code warehouse address: https://github.com/kgepachong/crawler/
JavaScript encryption code
/* ==================================
# @Time : 2022-01-11
# @Author : 微信公众号:K哥爬虫
# @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;
}
// 测试样例
// console.log(encrypt("15555555555"))
Python login code
# ==================================
# @Time : 2022-01-11
# @Author : 微信公众号:K哥爬虫
# @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 = "脱敏处理,完整代码关注 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 = "脱敏处理,完整代码关注 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 = "脱敏处理,完整代码关注 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 = "脱敏处理,完整代码关注 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 = "脱敏处理,完整代码关注 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("请输入账号:")
pwd = input("请输入密码:")
get_session()
uuid = get_uuid()
code = ver_code()
login(phone, pwd, code, uuid)
if __name__ == '__main__':
main()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。