JS逆向基础

JS逆向基础

一、什么是JS逆向?

我们在网站进行账号登录的时候对网页源进行抓包就会发现我们输入的密码在后台会显示为一串由字母或数字等符号,这就是经过加密呈现的一段加密文字,而分析这些接口的加密算法并实现模拟调用的过程就叫做「逆向」。

逆向对于爬虫说是一个永远绕不开的话题,而我们所做的解密工作,通过解密步骤得到密码的过程,称为JS逆向。

我们将通过一个简单的案例来讲解JS的分析思路。

二、接口抓包

首先我们先点击网站的的登陆页面,打开网站的控制台,点击1(网络),再点击2(fetch/XHR),然后再点击3(清空信息),我们在进行输入(4)账号密码和验证码,为了教学,故意输错密码,点击登录,控制台跳出6(登陆包),在其中可以获取Signature(7)

点击1,在点击2,即可出现搜索页面(3),我们将Signature输入,即可获取Signature在网页源代码中的生成函数

可知3即为需要逆向分析的数据

三、逆向分析

U.Signature = Object(f.a)(U, M, l.j ? l.g : l.c);

按照下图操作获取Object(f.a)函数和U,M,和 l.j ? l.g : l.c的值



将代码复制到js文件中,运行代码报错,提示找不到f函数,将代码中相关函数全部复制

源码

js 复制代码
l = {
    key: cryptoJs.enc.Utf8.parse("fX@VyCQVvpdj8RCa"),
    iv: cryptoJs.enc.Utf8.parse(function (t) {
        for (var e = "", i = 0; i < t.length - 1; i += 2) {
            var n = parseInt(t[i] + "" + t[i + 1], 16);
            e += String.fromCharCode(n)
        }
        return e
    }("00000000000000000000000000000000"))
}
    , v = function (data) {
    return function (data) {
        return cryptoJs.AES.encrypt(data, l.key, {
            iv: l.iv,
            mode: cryptoJs.mode.CBC,
            padding: cryptoJs.pad.Pkcs7
        }).toString()
    }(data)
}
    , d = function (data) {
    return cryptoJs.MD5(data).toString()
}
    , f = function (t) {
    var e = "";
    return Object.keys(t).sort().forEach((function (n) {
            e += n + ("object" === typeof (t[n]) ? JSON.stringify(t[n], (function (t, e) {
                    return "number" == typeof e && (e = String(e)),
                        e
                }
            )).replace(/\//g, "\\/") : t[n])
        }
    )),
        e
}

h = function (t) {
    var data = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}
        , e = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "a75846eb4ac490420ac63db46d2a03bf"
        , n = e + f(data) + f(t) + e;
    return n = d(n),
        n = v(n)
}


U = {
    "App-Ver": "",
    "Os-Ver": "",
    "Device-Ver": "",
    "Imei": "",
    "Access-Token": "",
    "Timestemp": 1700571511,
    "NonceStr": "170057151176dni",
    "App-Id": "4ac490420ac63db4",
    "Device-Os": "web"
};

let L = {
    "username": "qweqweqeqweqwe",
    "password": "qweqweqweqweqwe",
    "code": "65xv",
    "hdn_refer": "https://www.epwk.com/"
};

C = 'a75846eb4ac490420ac63db46d2a03bf'

console.log(h(U, L, C))

又报错

导入crypto-js库替换o函数

const cryptoJs = require("crypto-js")
js 复制代码
const cryptoJs = require("crypto-js")

l = {
    key: cryptoJs.enc.Utf8.parse("fX@VyCQVvpdj8RCa"),
    iv: cryptoJs.enc.Utf8.parse(function (t) {
        for (var e = "", i = 0; i < t.length - 1; i += 2) {
            var n = parseInt(t[i] + "" + t[i + 1], 16);
            e += String.fromCharCode(n)
        }
        return e
    }("00000000000000000000000000000000"))
}
    , v = function (data) {
    return function (data) {
        return cryptoJs.AES.encrypt(data, l.key, {
            iv: l.iv,
            mode: cryptoJs.mode.CBC,
            padding: cryptoJs.pad.Pkcs7
        }).toString()
    }(data)
}
    , d = function (data) {
    return cryptoJs.MD5(data).toString()
}
    , f = function (t) {
    var e = "";
    return Object.keys(t).sort().forEach((function (n) {
            e += n + ("object" === typeof (t[n]) ? JSON.stringify(t[n], (function (t, e) {
                    return "number" == typeof e && (e = String(e)),
                        e
                }
            )).replace(/\//g, "\\/") : t[n])
        }
    )),
        e
}

h = function (t) {
    var data = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}
        , e = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "a75846eb4ac490420ac63db46d2a03bf"
        , n = e + f(data) + f(t) + e;
    return n = d(n),
        n = v(n)
}


U = {
    "App-Ver": "",
    "Os-Ver": "",
    "Device-Ver": "",
    "Imei": "",
    "Access-Token": "",
    "Timestemp": 1700571511,
    "NonceStr": "170057151176dni",
    "App-Id": "4ac490420ac63db4",
    "Device-Os": "web"
};

let L = {
    "username": "qweqweqeqweqwe",
    "password": "qweqweqweqweqwe",
    "code": "65xv",
    "hdn_refer": "https://www.epwk.com/"
};

C = 'a75846eb4ac490420ac63db46d2a03bf'

console.log(h(U, L, C))

运行又报错,替换r.a函数,

"object" === typeof (t[n]) 

最后代码运行出Signature

最后将js代码转成python,再与爬虫相结合最后写出代码

python 复制代码
import requests

cookies = {
    'Hm_lvt_387b8f4fdb89d4ea233922bdc6466394': '1698224816,1699438386,1700570522',
    'PHPSESSID': 'ca8646d868cd69a35397b2a42dba42d0e7a8f02b',
    'time_diff': '0',
    'XDEBUG_SESSION': 'XDEBUG_ECLIPSE',
    'adbanner_city': '%E5%8C%97%E4%BA%AC%E5%B8%82',
    'banners_show_cookie_ip': '221.216.142.177',
    'login_referer': 'https%3A%2F%2Fwww.epwk.com%2F',
    'Hm_lpvt_387b8f4fdb89d4ea233922bdc6466394': '1700570526',
    'login_fail_need_graphics': '0',
}

headers = {
    'Accept': 'application/json, text/plain, */*',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Access-Token': '',
    'App-Id': '4ac490420ac63db4',
    'App-Ver': '',
    'CHOST': 'www.epwk.com',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded',
    # 'Cookie': 'Hm_lvt_387b8f4fdb89d4ea233922bdc6466394=1698224816,1699438386,1700570522; PHPSESSID=ca8646d868cd69a35397b2a42dba42d0e7a8f02b; time_diff=0; XDEBUG_SESSION=XDEBUG_ECLIPSE; adbanner_city=%E5%8C%97%E4%BA%AC%E5%B8%82; banners_show_cookie_ip=221.216.142.177; login_referer=https%3A%2F%2Fwww.epwk.com%2F; Hm_lpvt_387b8f4fdb89d4ea233922bdc6466394=1700570526; login_fail_need_graphics=0',
    'Device-Os': 'web',
    'Device-Ver': '',
    'Imei': '',
    'NonceStr': '1700570738pdcom',
    'Origin': 'https://www.epwk.com',
    'Os-Ver': '',
    'Pragma': 'no-cache',
    'Referer': 'https://www.epwk.com/login.html',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    'Signature': 'Ks5z+mbEmnNOLXsZKuOq84sn8ATLQmZxN9RmH1Gi4yuPWQWo+GYbhylLq4jxFy3F',
    'Timestemp': '1700570738',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
    'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"macOS"',
}

data = {
    'username': 'qweqweqeqweqwe',
    'password': 'qweqweqweqweqwe',
    'code': 'aaaa',
    'hdn_refer': 'https://www.epwk.com/',
}

response = requests.post('https://www.epwk.com/api/epwk/v1/user/login', cookies=cookies, headers=headers, data=data)
print(response.text)
相关推荐
Ysjt | 深2 分钟前
C++多线程编程入门教程(优质版)
java·开发语言·jvm·c++
ephemerals__8 分钟前
【c++丨STL】list模拟实现(附源码)
开发语言·c++·list
码农飞飞12 分钟前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货13 分钟前
Rust 的简介
开发语言·后端·rust
湫ccc21 分钟前
《Python基础》之基本数据类型
开发语言·python
Matlab精灵22 分钟前
Matlab函数中的隐马尔可夫模型
开发语言·matlab·统计学习
Microsoft Word23 分钟前
c++基础语法
开发语言·c++·算法
数据小爬虫@25 分钟前
如何利用java爬虫获得淘宝商品评论
java·开发语言·爬虫
qq_1728055933 分钟前
RUST学习教程-安装教程
开发语言·学习·rust·安装
wjs202440 分钟前
MongoDB 更新集合名
开发语言