今天我们来逆向某大网校的登录
输入账号密码:浏览器的preserve log要✔
不然的话,登录成功会刷新页面,会重定向
1.分析:
password很明显是被加密的
我们通过搜索这个,目标url,定位到加密的函数
进入encryptFn():看到JSEncrypt,确定是res加密
接下来开始逆向.
我们从登录位置开始. 第一个搞定的. 是那个烦人的验证码:
抓包,拿到请求验证码的url:
这个请求是需要cookie的, 想想也应该如此.
因为服务器要知道这张图片给哪个客户端使用了. 就必须借助cookie来判别不同的客户端.
所以. 整个流程应该是:
- 进入登录页, 加载到cookie
- 访问验证码url, 获取到验证码.
- 访问getTime 在后续的密码加密时是需要这个api返回的data的
- 准备好用户名和密码. 对密码进行加密
- 发送登录请求.
- 得到结果
2.代码:
这里我们使用图鉴的api来识别验证码:
import requests
import base64
import json
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
#这里使用图鉴来识别验证码
def base64_api(b64):
data = {"username": "xxx", "password": "xxx", "typeid": 3, "image": b64}
result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)
if result['success']:
return result["data"]["result"]
else:
return result["message"]
return ""
session = requests.session()
session.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
}
# 进入登录页, 目的: 加载cookie
login_url = "https://user.wangxiao.cn/login?url=http%3A%2F%2Fks.wangxiao.cn%2F"
session.get(login_url)
# 根据实际案例来.
session.headers['Content-Type'] = "application/json;charset=UTF-8"
# 下载验证码图片
verify_img_url = "https://user.wangxiao.cn/apis//common/getImageCaptcha"
img_resp = session.post(verify_img_url)
img_resp_json = img_resp.json()
img_base64 = img_resp_json.get("data").split(",")[-1]
with open("tu.png", mode="wb") as f:
f.write(base64.b64decode(img_base64))
# 识别验证码
verify_code = base64_api(img_base64)
# rsa加密(密码+时间)
# 在加密之前, 需要访问getTime, 获取到一个时间.
getTime_url = "https://user.wangxiao.cn/apis//common/getTime"
getTime_resp = session.post(getTime_url)
getTime_json = getTime_resp.json()
getTime = getTime_json.get('data')
login_name = "账号"
password_ming = "密码"
# rsa的公钥: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA5Zq6ZdH/RMSvC8WKhp5gj6Ue4Lqjo0Q2PnyGbSkTlYku0HtVzbh3S9F9oHbxeO55E8tEEQ5wj/+52VMLavcuwkDypG66N6c1z0Fo2HgxV3e0tqt1wyNtmbwg7ruIYmFM+dErIpTiLRDvOy+0vgPcBVDfSUHwUSgUtIkyC47UNQIDAQAB"
# 把公钥处理成字节
rsa_key_bs = base64.b64decode("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA5Zq6ZdH/RMSvC8WKhp5gj6Ue4Lqjo0Q2PnyGbSkTlYku0HtVzbh3S9F9oHbxeO55E8tEEQ5wj/+52VMLavcuwkDypG66N6c1z0Fo2HgxV3e0tqt1wyNtmbwg7ruIYmFM+dErIpTiLRDvOy+0vgPcBVDfSUHwUSgUtIkyC47UNQIDAQAB")
pub_key = RSA.importKey(rsa_key_bs)
rsa = PKCS1_v1_5.new(pub_key)
# 进行rsa加密, 加密的内容是 密码+时间
password_mi_bs = rsa.encrypt((password_ming+getTime).encode("utf-8"))
# 加密后的字节. 处理成base64
password_mi = base64.b64encode(password_mi_bs).decode()
login_data = {
"imageCaptchaCode": verify_code,
"password": password_mi,
"userName": login_name
}
password_login_url = "https://user.wangxiao.cn/apis//login/passwordLogin"
login_resp = session.post(password_login_url, data=json.dumps(login_data))
login_json = login_resp.json()
login_success_data = login_json.get("data")
# 登陆成功了之后. 应该可以获取数据了.
注意:
明明已经登陆成功了. 但是后续请求数据的时候. 拿不到数据.
登录之后的分析,在页面源码中有:
zdAjax(paramss, (ress) => {
var param = {
url: '/login/passwordLogin',
data: {
userName: username,
password: encryptFn(pwd + '' + ress.data),
imageCaptchaCode: imgCode,
},
}
// let param = {
// url: '/login/passwordLogin',
// data: {
// userName: username,
// password:encryptFn(pwd),
// imageCaptchaCode: imgCode
// }
// } ;
//去请求接口
zdAjax(param, (res) => {
if (res.code == 0) {
if ($('#auto-login').is(':checked')) {
//自动登录
keepOurCookie12('autoLogin', true, 30)
keepOurCookie12('userInfo', JSON.stringify(res.data), expiresDay)
keepOurCookie12('token', res.data.token, expiresDay)
syncLogin(res.data, expiresDay)
} else {
keepOurCookie12('autoLogin', null)
keepOurCookie12('userInfo', JSON.stringify(res.data))
keepOurCookie12('token', res.data.token)
syncLogin(res.data)
}
login.jump(res.data.isBindingMobile)
} else if (res.code == '9') {
//密码错误达到了两次
login.getImgCode($('#nimg-code .img-code-click'))
$('#nimg-code').addClass('show')
layer.msg(res.msg)
} else {
layer.msg(res.msg)
}
})
}
也就是说,请求成功后,还对cookie进行了处理:
需要在原python代码中添加cookie:
session.cookies['autoLogin'] = 'null'
session.cookies['userInfo'] = json.dumps(login_success_data)
session.cookies['token'] = login_success_data.get("token")
session.cookies['UserCookieName'] = login_success_data.get("userName")
session.cookies['OldUsername2'] = login_success_data.get("userNameCookies")
session.cookies['OldUsername'] = login_success_data.get("userNameCookies")
session.cookies['OldPassword'] = login_success_data.get("passwordCookies")
session.cookies['UserCookieName_'] = login_success_data.get("userName")
session.cookies['OldUsername2_'] = login_success_data.get("userNameCookies")
session.cookies['OldUsername_'] = login_success_data.get("userNameCookies")
session.cookies['OldPassword_'] = login_success_data.get("passwordCookies")
session.cookies[login_success_data.get('userName')+"_exam"] = login_success_data.get("sign")
#然后再去请求登录之后想要的url~