关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶、JS/安卓逆向等技术干货!

声明

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

逆向目标

  • 目标:某 e 网通登录接口
  • 主页:aHR0cHM6Ly93ZWIuZXd0MzYwLmNvbS9yZWdpc3Rlci8jL2xvZ2lu
  • 接口:aHR0cHM6Ly9nYXRld2F5LmV3dDM2MC5jb20vYXBpL2F1dGhjZW50ZXIvdjIvb2F1dGgvbG9naW4vYWNjb3VudA==
  • 逆向参数:
    • Request Headers:sign: 3976F10977FC65F9CB967AEF79E508BD
    • Request Payload:password: "A7428361DEF118911783F446A129FFCE"

逆向过程

抓包分析

来到某 e 网通的登录页面,随便输入一个账号密码登陆,抓包定位到登录接口为 aHR0cHM6Ly9nYXRld2F5LmV3dDM2MC5jb20vYXBpL2F1dGhjZW50ZXIvdjIvb2F1dGgvbG9naW4vYWNjb3VudA==,请求头里,有一个 sign,Payload 里,密码 password 被加密处理了。

参数逆向

sign

首先来看一下请求头的 sign,尝试直接搜索一下,发现并不是经过某些请求返回的数据,观察一下其他请求,可以发现同样有 sign,而且每次请求的值都不一样:

由此可以初步判断这个值应该是通过 JS 生成的,全局搜索关键字 sign:,可以分别在 request.js、request.ts 两个文件里面看到疑似 sign 赋值的地方,埋下断点调试,成功断下,原理也很简单,时间戳加上一串固定的字符,经过 MD5 加密后再转大写即可。

使用 Python 实现:

import time
import hashlib timestamp = str(int(time.time() * 1000))
sign = hashlib.md5((timestamp + 'bdc739ff2dcf').encode(encoding='utf-8')).hexdigest().upper()
print(sign)

password

password 是明文密码经过加密后得到的值,如果尝试直接去搜索的话,会发现出来的值非常非常多,要想找到准确的值难度巨大:

可以看到这条请求是 XHR 请求,本次我们使用 XHR 断点的方法来定位具体的加密位置,通过本次案例,我们来学习一下具体是如何跟进调用栈、如何通过上下文来定位具体的加密位置。

切换到 Network 选项卡,找到登陆请求,鼠标移动到 Initiator 选项卡下的 JS 上,可以看到其调用栈,如果站点的加密方式比较简单,没有太多混淆的话,调用栈里面就可以看到 login、send、post、encrypt 等等之类的关键词,这种情况下就可以直接点进去,比较容易找到加密的地方,但是大多数站点对于函数名、变量名都做了混淆,和本案例一样,调用栈里面显示的都是一些单个或者多个无规则的字母的函数,无法直接定位,此时就需要我们从最后一个函数往前慢慢找。

点击进入最后一个函数,即 Y 函数,它位于调用栈的最顶层,表示经过此函数后,浏览器就会发送登录的请求,密码的加密过程已经处理完毕。在此函数埋下断点,可以在右侧的 Call Stack 看到调用栈,从下到上,表示的是点击登陆后,先后调用的函数的执行过程:

想要找到具体的加密位置,我们就要依次往前找,挨个函数进行分析,例如往前定位到倒数第二个调用栈,即 o 函数,可以看到传进来的 params 参数里面就包含了已加密的密码信息,这说明加密操作肯定在此函数之前:

根据这种思路,一步一步往下跟进调用栈,可以看到在 utils.ts 里面执行了一个匿名函数,其中调用了一个 passwordEncrypt 函数,通过函数名就可以看出基本上就是密码加密的函数了:

在此处埋下断点进行调试,传进来的是明文密码,passwordEncrypt 实际上是调用的 encode.ts 中的 O 函数:

跟进 O 函数,引用了 crypto-js 加密模块,很明显的 AES 加密,本地改写一下就行了。

本次的案列加密比较简单,但是加密函数隐藏得比较好,需要耐心跟进调用栈,通过直接搜索的话,结果太多,是不太容易定位加密函数的,本次案例中跟进到一个函数后,可以很清楚的看到加密的地方,那么有的站点可能混淆得更加厉害,是看不出来有加密函数的,这种情况下就需要我们注意参数的变化情况,如果在这个调用栈看到的是加密后的参数,在上一个调用栈里面看到的是明文的参数,那么加密的操作必定在这两个调用栈之间,埋下断点,仔细分析即可。

完整代码

GitHub 关注 K 哥爬虫,持续分享爬虫相关代码!欢迎 star !https://github.com/kgepachong/

以下只演示部分关键代码,不能直接运行!完整代码仓库地址:https://github.com/kgepachong/crawler/

JavaScript 加密代码

CryptoJS = require("crypto-js")

const key = CryptoJS.enc.Utf8.parse("20171109124536982017110912453698");
const iv = CryptoJS.enc.Utf8.parse('2017110912453698'); //十六位十六进制数作为密钥偏移量 function getEncryptedPassword(word) {
let srcs = CryptoJS.enc.Utf8.parse(word);
let encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString().toUpperCase();
} // 测试样例
// console.log(getEncryptedPassword("123457"))

Python 登录代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import time
import hashlib import execjs
import requests login_url = '脱敏处理,完整代码关注 GitHub:https://github.com/kgepachong/crawler'
session = requests.session() def get_sign():
timestamp = str(int(time.time()*1000))
sign = hashlib.md5((timestamp + 'bdc739ff2dcf').encode(encoding='utf-8')).hexdigest().upper()
return sign def get_encrypted_parameter(password):
with open('ewt360_encrypt.js', 'r', encoding='utf-8') as f:
ewt360_js = f.read()
encrypted_password = execjs.compile(ewt360_js).call('getEncryptedPassword', password)
return encrypted_password def login(sign, username, encrypted_password):
headers = {
'sign': sign,
'timestamp': str(int(time.time()*1000)),
'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
data = {
'autoLogin': True,
'password': encrypted_password,
'platform': 1,
'userName': username
}
response = session.post(url=login_url, headers=headers, json=data)
print(response.json()) def main():
username = input('请输入登录账号: ')
password = input('请输入登录密码: ')
sign = get_sign()
encrypted_password = get_encrypted_parameter(password)
login(sign, username, encrypted_password) if __name__ == '__main__':
main()

【JS 逆向百例】如何跟栈调试?某 e 网通 AES 加密分析的更多相关文章

  1. 通过JS逆向ProtoBuf 反反爬思路分享

    前言 本文意在记录,在爬虫过程中,我首次遇到Protobuf时的一系列问题和解决问题的思路. 文章编写遵循当时工作的思路,优点:非常详细,缺点:文字冗长,描述不准确 protobuf用在前后端传输,在 ...

  2. JS逆向之补环境过瑞数详解

    JS逆向之补环境过瑞数详解 "瑞数" 是逆向路上的一座大山,是许多JS逆向者绕不开的一堵围墙,也是跳槽简历上的一个亮点,我们必须得在下次跳槽前攻克它!! 好在现在网上有很多讲解瑞数 ...

  3. 网络爬虫之记一次js逆向解密经历

    1 引言 数月前写过某网站(请原谅我的掩耳盗铃)的爬虫,这两天需要重新采集一次,用的是scrapy-redis框架,本以为二次爬取可以轻松完成的,可没想到爬虫启动没几秒,出现了大堆的重试提示,心里顿时 ...

  4. 这个爬虫JS逆向加密任务,你还不来试试?逆向入门级,适合一定爬虫基础的人

    友情提示:在博客园更新比较慢,有兴趣的关注知识图谱与大数据公众号吧.这次选择苏宁易购登录密码加密,如能调试出来代表你具备了一定的JS逆向能力,初学者建议跟着内容调试一波,尽量独自将JS代码抠出来,实在 ...

  5. 爬虫必看,每日JS逆向之爱奇艺密码加密,今天你练了吗?

    友情提示:优先在公众号更新,在博客园更新较慢,有兴趣的关注一下知识图谱与大数据公众号,本次目标是抠出爱奇艺passwd加密JS代码,如果你看到了这一篇,说明你对JS逆向感兴趣,如果是初学者,那不妨再看 ...

  6. JS逆向之浏览器补环境详解

    JS逆向之浏览器补环境详解 "补浏览器环境"是JS逆向者升职加薪的必备技能,也是工作中不可避免的操作. 为了让大家彻底搞懂 "补浏览器环境"的缘由及原理,本文将 ...

  7. 兄弟,你爬虫基础这么好,需要研究js逆向了,一起吧(有完整JS代码)

    这几天的确有空了,看更新多快,专门研究了一下几个网站登录中密码加密方法,比起滑块验证码来说都相对简单,适合新手js逆向入门,大家可以自己试一下,试不出来了再参考我的js代码.篇幅有限,完整的js代码在 ...

  8. 兄弟,别再爬妹子图了整点JS逆向吧--陆金所密码加密破解

    好久没有写爬虫文章了,今晚上得空看了一下陆金所登录密码加密,这个网站js加密代码不难,适合练手,篇幅有限,完整js代码我放在了这里从今天开始种树,不废话,直接开整. 前戏热身 打开陆金所网站,点击到登 ...

  9. JS逆向-抠代码的第一天【手把手学会抠代码】

    首先声明,本人经过无数次摸爬滚打及翻阅各类资料,理论知识极其丰富,但是抠代码怎么都抠不会. 无奈之下,只能承认:这个活,需要熟练度. 本文仅对部分参数进行解析,有需要调用,请自行根据现实情况调整. 第 ...

  10. 我去!爬虫遇到JS逆向AES加密反爬,哭了

    今天准备爬取网页时,遇到『JS逆向AES加密』反爬.比如这样的: 在发送请求获取数据时,需要用到参数params和encSecKey,但是这两个参数经过JS逆向AES加密而来. 既然遇到了这个情况,那 ...

随机推荐

  1. mysql新增数据库新增用户并授权用户

    -- 创建数据库CREATE DATABASE  baseName; -- 创建用户CREATE USER 'userName' @ '访问限制' IDENTIFIED BY 'password'; ...

  2. 对话 BitSail Contributor | 刘啸:参与开源,提升自我技术力

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 2022 年 10 月,字节跳动 BitSail 数据引擎正式开源.同期,社区推出 Contributor 激励计 ...

  3. 电商流量分析怎么做?试试这款数据工具 DataLeap!

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 作为成熟的电商模式,货架场景可以让商家以更低的门槛入驻,让消费者完成更高销量的购买和复购. 在这一场景下,运营人员 ...

  4. 用 docker 部署 folkmq 消息中间件

    docker run -p 18602:18602 -p 8602:8602 noearorg/folkmq-server:1.0.19

  5. Netty 框架学习 —— 初识 Netty

    Netty 是一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端 Java 网络编程 早期的 Java API 只支持由本地系统套接字库提供的所谓的阻塞函数, ...

  6. ASP.NET Web API Demo OwinSelfHost 自宿主 Swagger Swashbuckle 在线文档

    新建Web API工程 选Empty,勾选Web API,不要选择Web API,那样会把MVC勾上,这里不需要MVC Web API工程属性 XML文件用于生成在线文档 新建Windows服务作为W ...

  7. AcWing 每日一题 - Summer

    本篇解题记录题源来自 AcWing 的 Summer 每日一题 补题链接:Here 2021/07/01 done Week 1 星期一 AcWing 3485. 最大异或和 (Hard 思路 先求出 ...

  8. 版本升级 | 兼容VSCode及全系IDE,代码风险一键查询

    OpenSCA插件上新啦~ Jetbrains IDE插件全新升级,很多朋友提了需求的VSCode咱也支持上啦~ 当然,CEC-IDE也是兼容的(手动狗头). OpenSCA-VSCode-plugi ...

  9. uniapp解决图形验证码问题及arraybuffer二进制转base64格式图片

    https://www.cnblogs.com/huihuihero/p/13183031.html

  10. docker 原理之 mount namespace(下)

    1. mount namespace mount namespace 通过隔离文件系统挂载点对隔离文件系统提供支持.使用 unshare 构造 mount namespace 如下: root@chu ...