【JS 逆向百例】房天下登录接口参数逆向

声明
本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!
逆向目标
目标:房天下账号密码登录
逆向参数:
Form Data:
pwd: 044b527dba64d1e82657668beae1d61e4d86643d231792c78d5c538461a146b01c8e28d98b14915a11758deb6095aba16688a07427150434681949529f02e808e8891e1f90b5c91d42058a83f2c6902bd69825577dc4efb993f1aa4c9bb43a2bbe1acad5781a8738614ddafbda3cca99a0c03fb634d8e1001f25bca59a8d421b`
逆向过程
抓包分析
随便输入一个账号密码,点击登陆,抓包定位到登录接口为 https://passport.fang.com/login.api ,POST 请求,Form Data 里,密码 pwd 被加密处理了。

参数逆向
加密参数只有一个 pwd,直接全局搜索,出现一个 loginbypassword.js,很明显就是加密的 JS,这个 JS 贴心的写上了中文注释,直接来到登录模块,埋下断点:

uid: that.username.val(),
pwd: encryptedString(key_to_encode, that.password.val()),
Service: that.service.val(),
AutoLogin: that.autoLogin.val()
encryptedString 这个函数可以看到在一个叫做 RSA.min.js 的加密 JS 里,很明显的 RSA 加密,直接 copy 下来就好了,key_to_encode 这个参数可以直接在首页搜到,可以看到是向 RSAKeyPair 函数传入参数得到的:

完整代码
以下只演示部分关键代码,完整代码可在 GitHub 下载:https://github.com/kuaidaili/crawler/tree/main/passport_fang_com
fang_encrypt.js
function setMaxDigits(n) {}
function BigInt(n) {}
function biFromDecimal(n) {}
// 此处省略 N 个函数
function twoDigit(n) {}
function encryptedString(n, t) {}
function decryptedString(n, t) {}
var biRadixBase = 2, biRadixBits = 16, bitsPerDigit = biRadixBits, biRadix = 65536, biHalfRadix = biRadix >>> 1,
biRadixSquared = biRadix * biRadix, maxDigitVal = biRadix - 1, maxInteger = 9999999999999998, maxDigits, ZERO_ARRAY,
bigZero, bigOne, dpl10, lr10, hexatrigesimalToChar, hexToChar, highBitMasks, lowBitMasks;
setMaxDigits(20);
dpl10 = 15;
lr10 = biFromNumber(1e15);
hexatrigesimalToChar = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
hexToChar = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
highBitMasks = [0, 32768, 49152, 57344, 61440, 63488, 64512, 65024, 65280, 65408, 65472, 65504, 65520, 65528, 65532, 65534, 65535];
lowBitMasks = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535];
setMaxDigits(129);
function getEncryptedPassword(pwd, n, i, t) {
var key_to_encode = new RSAKeyPair(n, i, t);
return encryptedString(key_to_encode, pwd)
}
// 测试样例
// console.log(getEncryptedPassword("16521689404", "010001", "", "978C0A92D2173439707498F0944AA476B1B62595877DD6FA87F6E2AC6DCB3D0BF0B82857439C99B5091192BC134889DFF60C562EC54EFBA4FF2F9D55ADBCCEA4A2FBA80CB398ED501280A007C83AF30C3D1A142D6133C63012B90AB26AC60C898FB66EDC3192C3EC4FF66925A64003B72496099F4F09A9FB72A2CF9E4D770C41"))
fang_login.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
import execjs
import requests
index_url = 'https://passport.fang.com/'
login_url = 'https://passport.fang.com/login.api'
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
session = requests.session()
def get_key_to_encode():
headers = {'User-Agent': user_agent}
response = session.get(url=index_url, headers=headers)
key_to_encode = re.findall(r'RSAKeyPair\((.*)\);', response.text)[0].replace('"', '').split(', ')
return key_to_encode
def get_encrypted_password(key_to_encode, pwd):
n, i, t = key_to_encode[0], key_to_encode[1], key_to_encode[2]
with open('fang_encrypt.js', 'r', encoding='utf-8') as f:
fang_js = f.read()
encrypted_pwd = execjs.compile(fang_js).call('getEncryptedPassword', pwd, n, i, t)
return encrypted_pwd
def login(encrypted_password, uid):
headers = {
'User-Agent': user_agent,
'X-Requested-With': 'XMLHttpRequest',
'Host': 'passport.fang.com',
'Origin': 'https://passport.fang.com',
'Referer': 'https://passport.fang.com/?backurl=http%3a%2f%2fmy.fang.com%2f',
'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
data = {
'uid': uid,
'pwd': encrypted_password,
'Service': 'soufun-passport-web',
'AutoLogin': 1
}
response = session.post(url=login_url, data=data, headers=headers)
print(response.json())
def main():
# 16521689404
uid = input('请输入登录账号:')
pwd = input('请输入登录密码:')
rsa_key = get_key_to_encode()
encrypted_pwd = get_encrypted_password(rsa_key, pwd)
login(encrypted_pwd, uid)
if __name__ == '__main__':
main()

【JS 逆向百例】房天下登录接口参数逆向的更多相关文章
- python爬虫-房天下-登录
房天下-登录 本次爬取的网址为:https://passport.fang.com 一.分析请求 输入用户名和密码,点击登录按钮 请求的参数为: uid: 123456789 pwd: 64ccd42 ...
- 再说表单验证,在Web Api中使用ModelState进行接口参数验证
写在前面 上篇文章中说到了表单验证的问题,然后尝试了一下用扩展方法实现链式编程,评论区大家讨论的非常激烈也推荐了一些很强大的验证插件.其中一位园友提到了说可以使用MVC的ModelState,因为之前 ...
- 前端跳转处理--房天下的访问页面部分ip自动跳转到登录页面的解决办法(xjl456852原创)
朋友说自己在访问房天下的页面时,他们页面进行了跳转,跳转到登录页面,说是前端跳转.让我也看看,我看我的机器没有进行跳转. 后来就发现有的机器在访问页面会自动跳转到登录页面.有的不会进行跳转. 比如访问 ...
- Java使用正则表达式取网页中的一段内容(以取Js方法为例)
关于正则表达式: 表1.常用的元字符 代码 说明 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配字符串 ...
- Django商城项目笔记No.10用户部分-登录接口
Django商城项目笔记No.10用户部分-登录接口 添加url路由 接下来第二步,增加返回内容: 增加结果如下: 配置:上边的方法定义了返回的内容都有哪些,那这个方法jwt还不知道,需要配置: 修改 ...
- Node.js开发入门—使用cookie保持登录
这次来做一个站点登录的小样例,后面会用到. 这个演示样例会用到Cookie.HTML表单.POST数据体(body)解析. 第一个版本号,我们的用户数据就写死在js文件中. 第二个版本号会引入Mong ...
- Java设计模式百例 - 观察者模式
观察者(Observer)模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,主体对象的状态变化会通知所有观察者对象.观察者模式又叫做发布-订阅(Publish/Subscribe ...
- (转)python编写登录接口
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://506554897.blog.51cto.com/2823970/1907262 ...
- httprunner学习1-环境与登录接口案例
前言 HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试. 具有以下优点: 继承 Requests 的全部特性,轻松实 ...
- koa 项目实战(七)登录接口
1.登录接口 /** * @route POST api/users/login * @desc 登录接口地址 * @access 接口是公开的 */ router.post('/login', as ...
随机推荐
- Skywalking 8.1 Docker 服务端部署
前置条件 Docker 安装 Elasticsearch ### 部署服务端 skywalking-oap-server docker pull apache/skywalking-oap-serve ...
- SpringBoot Scheduled 常见用法
外部统一管理可用 xxl-job ,将各定时任务集中管理,灵活改变执行频率,支持某一个定时器集群处理,避免多服务启动时,每个服务都执行(重复执行) 比如我的API服务里有一个定时任务,将API做成集群 ...
- GO语言之环境搭建和基本命令
目录 go语言基础 下载go编译器 go目录简介 gopath简介 环境变量配置 GOPATH PATH go语言项目结构 IDE下载与配置 安装goland goland里添加goroot和gopa ...
- Java 键值对数据本地保存与读取
代码: package com.sux.demo.utils; import com.alibaba.fastjson.JSONObject; import java.io.File; import ...
- AtCoder Beginner Contest 217 D~E
比赛链接:Here ABC水题, D - Cutting Woods 题意:开始一根木棒长度为 \(n\) 并以 \(1\) 为单位在木棒上标记\((1\sim n)\) ,输出 \(q\) 次操作 ...
- POJ - 2259 Team Queue (队列)
题目链接 https://vjudge.net/problem/POJ-2259 题解 在任何时刻,同一个小组的人只要来到了队伍,就会站在一起,所以我们建立一个队列q0存储队伍中所有小组的编号,再为每 ...
- CodeForces - 651A Joysticks ( 不难 但有坑 )
正式更换编译器为: VS Code 如何配置环境:click here 代码格式化工具:clang-format A. Joysticks 题目连接: http://www.codeforces.co ...
- vue计算属性computed传参
需求:根据不同的状态status,显示不同颜色的边框
- vue监听数组变化
1 // 触发更新视图 2 function updateView() { 3 console.log('视图更新') 4 } 5 6 // 重新定义数组原型 7 const oldArrayProp ...
- 玩转 Helm 之 upgrade
0. 前言 在 玩转 Helm 一文中,简略提到了 Helm upgrade 的策略. 在实际项目开发上,upgrade 多是调研的重点.基于此,这里对 upgrade 继续展开. 1. basic ...