链家登录加密分析

声明:本文章所有内容仅供学习使用,无其它任何目的,严禁用于商业用途和非法用途,否则产生一切后果均与作者无关

目标链接:aHR0cHM6Ly9jbG9naW4ubGlhbmppYS5jb20vbG9naW4/c2VydmljZT1odHRwcyUzQSUyRiUyRnd3dy5saWFuamlhLmNvbSUyRnVzZXIlMkZjaGVja2xvZ2luJTNGcmVkaXJlY3QlM0RodHRwcyUyNTNBJTI1MkYlMjUyRnNoLmxpYW5qaWEuY29tJTI1MkZjaGVuZ2ppYW8lMjUyRg==

1.抓包分析

在这里插入图片描述

加密参数 passwordloginTicketIdsrcId
多登录几次可以发现 srcId是固定的,那就剩下两外两个参数。搜索 loginTicketId 发现是 xhr请求返回的数据,下面还有一个 publickeykey值,
在这里插入图片描述

那就剩下最后一个 password,全局搜所发现有很多,我们可以选择 XHR断点
在这里插入图片描述

2.控制台调试

重新输入账号密码,直接在发包的地方断住了,并且可以看到 n 里面有加密的 passowrd 继续往前跟栈
在这里插入图片描述

跟到异步里面,发现这里有一个与运算,拉到最后发现有一些 publickey 是不是和我们前面看到的 publickey很像呢
在这里插入图片描述
我们在这个对象里面打上断点输入账号密码重新发一个请求
在这里插入图片描述
发现 Object(E.a)(l()(e, “credential.password”), l()(n.authInitialInfo, “publicKey.key”)) 加密后的数据和之前我们的 password很像而且长度一致,跟到 E.a 里面看看
在这里插入图片描述
发现有加密特征值 encryptsetPublicKey 基本可以判断出这里就是加密的地方,典型的 RSA加密,公钥是传过来的 e 值。
大概流程:第一次请求返回 setPublicKeyloginTicketId,用公钥进行 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)

4.最终结果

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值