声明:本文章所有内容仅供学习使用,无其它任何目的,严禁用于商业用途和非法用途,否则产生一切后果均与作者无关
目标链接:aHR0cHM6Ly9jbG9naW4ubGlhbmppYS5jb20vbG9naW4/c2VydmljZT1odHRwcyUzQSUyRiUyRnd3dy5saWFuamlhLmNvbSUyRnVzZXIlMkZjaGVja2xvZ2luJTNGcmVkaXJlY3QlM0RodHRwcyUyNTNBJTI1MkYlMjUyRnNoLmxpYW5qaWEuY29tJTI1MkZjaGVuZ2ppYW8lMjUyRg==
1.抓包分析
加密参数 password 、 loginTicketId、 srcId
多登录几次可以发现 srcId是固定的,那就剩下两外两个参数。搜索 loginTicketId 发现是 xhr请求返回的数据,下面还有一个 publickey 的 key值,
那就剩下最后一个 password,全局搜所发现有很多,我们可以选择 XHR断点
2.控制台调试
重新输入账号密码,直接在发包的地方断住了,并且可以看到 n 里面有加密的 passowrd 继续往前跟栈
跟到异步里面,发现这里有一个与运算,拉到最后发现有一些 publickey 是不是和我们前面看到的 publickey很像呢
我们在这个对象里面打上断点输入账号密码重新发一个请求
发现 Object(E.a)(l()(e, “credential.password”), l()(n.authInitialInfo, “publicKey.key”)) 加密后的数据和之前我们的 password很像而且长度一致,跟到 E.a 里面看看
发现有加密特征值 encrypt 和 setPublicKey 基本可以判断出这里就是加密的地方,典型的 RSA加密,公钥是传过来的 e 值。
大概流程:第一次请求返回 setPublicKey 和 loginTicketId,用公钥进行 RSA 加密,第二次参数带着加密后的 password 和 返回的 loginTicketId 进行第二次请求。
3.本地实现
# -*- coding: utf-8 -*-
import requests
import json
import base64
from binascii import b2a_hex, a2b_hex
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
def rsaEncryptByKey(content, key, encode="BASE64"):
"""
rsa 加密
:param content: 待加密文本
:param key: PublicKey
:param encode: BASE64/HEX
:return:
"""
key = "-----BEGIN PUBLIC KEY-----\n" + key + "\n-----END PUBLIC KEY-----"
rsakey = RSA.importKey(key)
cipher = PKCS1_v1_5.new(rsakey)
if encode == "BASE64":
cipher_text = base64.b64encode(cipher.encrypt(content.encode('utf-8')))
else:
cipher_text = b2a_hex(cipher.encrypt(content.encode('utf-8')))
print(cipher_text.decode('utf-8'))
return cipher_text.decode('utf-8')
def get_start():
url = "https://clogin.lianjia.com/authentication/initialize"
payload = json.dumps({
"service": "https://www.lianjia.com/user/checklogin?redirect=https%3A%2F%2Fsh.lianjia.com%2Fchengjiao%2F",
"context": {
"deviceId": "default",
"sign": "default"
},
"version": "2.0"
})
headers = {
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Content-Type': 'application/json',
'Accept': '*/*',
'Origin': 'https://clogin.lianjia.com',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
response = requests.request("POST", url, headers=headers, data=payload)
if response.status_code == 200:
datas = json.loads(response.text)
loginTicketId = datas.get("loginTicketId")
publicKey = datas.get("publicKey", {}).get("key")
return loginTicketId, publicKey
def get_data(psd: str, loginTicketId: str):
url = "https://clogin.lianjia.com/authentication/authenticate"
payload = json.dumps({
"mainAuthMethodName": "username-password",
"credential": {
"username": "自己注册",
"password": f"{psd}",
"ioaRunState": False,
"ioaMid": "{}",
"alertSt": "",
"ioaStateVersion": 2,
"encodeVersion": "1"
},
"withCaptcha": False,
"srcId": "eyJ0Ijoie1wiZGF0YVwiOlwiNzc0ZTNiMDc5YTE1YjJmYTMwNWYxMzU2MGNiZjBmOTE1NTg4OWFjODAzMTQ2NGU0NjU1YjJlYzNlZTI0NzBhNDQwZjgyOTliMjhmYTUzMTUyMzlhOTBkMzNlNTUxMzQ3MGNmYzUwMDNlNzQyM2U1NGMwYjgyNmJiMDNjMjNlMTQyYjMwZmZiYjhlMTg5ZDJiNjdlNzBmN2UzMjYwNWI1NWE2ODQyYTI3YTJjMzBkOWY4YTBlNjQ5YTA2ZTM3YjI2ZGFlYTE2ZjQzMjI2OGI0NTM5MzE5ODQ2NTczMmIyNWVlNzA3NzBmMDYwZmFlOGM5YzY5MjRiM2M4NGJjMTlkNlwiLFwia2V5X2lkXCI6XCIxXCIsXCJzaWduXCI6XCI1YzM4ODAzMVwifSIsInIiOiJodHRwczovL2Nsb2dpbi5saWFuamlhLmNvbS9sb2dpbj9zZXJ2aWNlPWh0dHBzJTNBJTJGJTJGd3d3LmxpYW5qaWEuY29tJTJGdXNlciUyRmNoZWNrbG9naW4lM0ZyZWRpcmVjdCUzRGh0dHBzJTI1M0ElMjUyRiUyNTJGc2gubGlhbmppYS5jb20lMjUyRmNoZW5namlhbyUyNTJGcGczJTI1MkYiLCJvcyI6IndlYiIsInYiOiIwLjEifQ==",
"context": {
"msg": "{}",
"deviceId": "default",
"sign": "default"
},
"version": "2.0",
"accountSystem": "customer",
"service": "https://www.lianjia.com/user/checklogin?redirect=https%3A%2F%2Fsh.lianjia.com%2Fchengjiao%2Fpg3%2F",
"loginTicketId": f"{loginTicketId}"
})
headers = {
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Content-Type': 'application/json',
'Accept': '*/*',
'Origin': 'https://clogin.lianjia.com',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://clogin.lianjia.com/authentication/sdk/init?version=2.0',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cookie': 'lianjia_uuid=4342ea1e-9def-6a17-bc1d-fb59f6b24403; lianjia_ssid=cbc06c0a-8352-573d-94a2-238d9e37bbd8; lianjia_ssid=cbc06c0a-8352-573d-94a2-238d9e37bbd8'
}
response = requests.request("POST", url, headers=headers, data=payload)
if response.status_code == 200:
datas = json.loads(response.text)
if datas.get("success") == True:
cookies = response.cookies.items()
cookie_result = ""
for cookie in cookies:
cookie_result += f"{cookie[0]}:{cookie[1]}; "
print(cookie_result)
if __name__ == '__main__':
loginTicketId, publicKey = get_start()
decrypt_text = "123456****"
psd = rsaEncryptByKey(content=decrypt_text, key=publicKey)
get_data(psd=psd, loginTicketId=loginTicketId)