pyexecjs原生js加密算法逆向

2024-01-23 03:44

本文主要是介绍pyexecjs原生js加密算法逆向,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 查看必要参数,得知sign签名

 

从堆栈自上到下依次查找源代码

如下图,找到后打上断点,得知e是输入的参数,说明b()是一个加密函数,点击进入查看底层函数

把1117这个函数内的三个方法CV到python中的一个js文件中,使用pyexecjs进行处理即可得到算法结果

 三个方法函数代码如下js:

function e(t, e) {(null == e || e > t.length) && (e = t.length);for (var n = 0, r = new Array(e); n < e; n++)r[n] = t[n];return r
}function n(t, e) {for (var n = 0; n < e.length - 2; n += 3) {var r = e.charAt(n + 2);r = "a" <= r ? r.charCodeAt(0) - 87 : Number(r),r = "+" === e.charAt(n + 1) ? t >>> r : t << r,t = "+" === e.charAt(n) ? t + r & 4294967295 : t ^ r}return t
}var r = null;function xx(t) {var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);if (null === i) {var a = t.length;a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))} else {for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, u = s.length, l = []; c < u; c++)"" !== s[c] && l.push.apply(l, function (t) {if (Array.isArray(t))return e(t)}(o = s[c].split("")) || function (t) {if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])return Array.from(t)}(o) || function (t, n) {if (t) {if ("string" == typeof t)return e(t, n);var r = Object.prototype.toString.call(t).slice(8, -1);return "Object" === r && t.constructor && (r = t.constructor.name),"Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0}}(o) || function () {throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),c !== u - 1 && l.push(i[c]);var p = l.length;p > 30 && (t = l.slice(0, 10).join("") + l.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + l.slice(-10).join(""))}for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = '320305.131321201' || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {var _ = t.charCodeAt(v);_ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),g[y++] = _ >> 18 | 240,g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,g[y++] = _ >> 6 & 63 | 128),g[y++] = 63 & _ | 128)}for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)b = n(b += g[x], w);return b = n(b, k),(b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),result = "".concat((b %= 1e6).toString(), ".").concat(b ^ f);return result;  // 返回结果
}

 上面是修改后的sj代码,如自己声明了xx()函数名,return 返回了一个结果。

参考图: 

d参数在控制台输出,gtk

window.gtk 可以在右键查看页面源代码中搜索gtk得到值

 进行替换

很多固定参数在js中找不到,就可以去查看页面源代码搜一下试试看。

 python代码:

# pip install pyexecjs# print(execjs.get().name)    # 当前运行时环境# import subprocess
# from functools import partial
#
# subprocess.Popen = partial(subprocess.Popen, encoding='utf-8')
#
# import execjs
#
# # 运行JavaScript代码
# result = execjs.eval("""
#     '马超_猴子_妲己_鲁班'.split('_')
# """)
#
# print(result)
#
# # compile() 加载一段js代码,通过call来访问这一段代码中的函数
# js = """
# function fn(a,b){
#     return a + b
# }
# function fn2(a,b){
#     return a * b
# }
# """
# a = execjs.compile(js)
# # 调用js中的函数
# ret = a.call('fn2', 10, 20)
# print(ret)
import json
import os
import requests
from pathlib import Path
import execjs
from fake_useragent import UserAgenturl = 'https://fanyi.baidu.com/v2transapi'
headers = {'User-Agent': UserAgent().random,"Cookie": '你的cookie'
}def fanyi(query):sign = get_sign(query)data = {'query': query,"from": "zh","to": "en","transtype": "enter","simple_means_flag": "3","sign": sign,"token": "你的token","domain": "common"}resp = requests.post(url, data=data, headers=headers)assert resp.status_code == 200dict_ret = json.loads(resp.text)try:ret = dict_ret['trans_result']['data'][0]['dst']return retexcept Exception as e:return edef get_sign(query):# 获取项目根目录BASE_DIR = Path(__file__).resolve().parents[1]# 构建文件路径file_path = os.path.join(BASE_DIR, 'utils', 'baidufanyi.js')f = open(file_path, mode='r', encoding='utf-8')# 加载js代码r = execjs.compile(f.read())# 调用(函数,参数)sign = r.call('xx', query)return signif __name__ == '__main__':print(fanyi('black'))

方法二:

"""
应用:百度翻译
urllib.request.Request
urllib.request.urlopen()
urllib.parse.urlencode()from表单参数
from: en: 表示源语言是英语(English)。
to: zh: 表示目标语言是中文(Chinese)。
query: apple: 表示要翻译的文本是 "apple"。
transtype: enter: 表示翻译类型是 "enter"。
simple_means_flag: 3: 表示简单翻译的标志,值为 3。
sign: 704513.926512: 表示请求的签名,可能是对其他参数的加密或哈希值。
token: bee1010145f198658719e143523967bf: 表示请求的令牌。
domain: common: 表示请求的领域是 "common"。
ts: 1702257690756: 表示请求的时间戳。
"""
import json
from urllib.request import Request, urlopen
from urllib.parse import quote, urlencodefrom fake_useragent import FakeUserAgenturl = 'https://fanyi.baidu.com/v2transapi'
headers = {'User-Agent': FakeUserAgent().random,"Cookie": "你的cookie"
}def fanyi(query):sign = calculate_sign(query)data = {'query': query,"from": "zh","to": "en","transtype": "translang","simple_means_flag": "3","sign": sign,"token": "11c16a562f2de40546a9f27f22f2b17d","domain": "common"}# Request()中的data参数是byte类型req = Request(url, data=urlencode(data).encode('utf-8'), headers=headers)resp = urlopen(req)assert resp.code == 200json_data = resp.read()content_encode = resp.getheader('Content-Type')content_encode = 'utf-8' if content_encode is None else content_encode.split('=')[-1]dict_ret = json.loads(json_data.decode('utf-8'))# print(dict_ret)try:ret = dict_ret['trans_result']['data'][0]['dst']return retexcept Exception as e:return '获取失败'"""
签名(sign)通常是通过对请求的关键参数进行加密或哈希运算而生成的,以确保请求的完整性和安全性。
签名的生成方式通常由服务端规定,并且在请求中包含签名参数。以下是一般的签名生成流程:获取待签名字符串: 将请求中的关键参数按照一定规则组织成一个字符串。进行加密或哈希运算: 将待签名字符串使用特定的算法进行加密或哈希运算,生成签名值。将签名值添加到请求参数中: 将生成的签名值作为请求的一部分,传递给服务端。
"""
# import hashlib
#
#
# def generate_signature(params, secret_key):
#     # 将参数按照特定规则排序并拼接成字符串
#     sorted_params = sorted(params.items())
#     concatenated_string = '&'.join([f"{key}={value}" for key, value in sorted_params])
#
#     # 将密钥拼接到待签名字符串末尾
#     concatenated_string += secret_key
#
#     # 使用 SHA256 算法生成签名
#     signature = hashlib.sha256(concatenated_string.encode()).hexdigest()
#
#     return signatureimport re
import mathdef translate_encrypt(text):i = "320305.131321201"o = re.findall(r'[\uD800-\uDBFF][\uDC00-\uDFFF]', text)if not o:t = len(text)if t > 30:text = text[:10] + text[math.floor(t / 2) - 5: math.floor(t / 2) + 5] + text[-10:]else:e = re.split(r'([\uD800-\uDBFF][\uDC00-\uDFFF])', text)S = []for C in range(len(e)):if e[C] != "":S.extend(list(e[C]))if C != len(e) - 1:S.append(o[C])g = len(S)if g > 30:text = ''.join(S[:10]) + ''.join(S[math.floor(g / 2) - 5: math.floor(g / 2) + 5]) + ''.join(S[-10:])u = "320305.131321201" if i is None else id = u.split(".")m = int(d[0]) if d[0] else 0s = int(d[1]) if d[1] else 0S = []for v in range(len(text)):A = ord(text[v])if A < 128:S.append(A)else:if 2048 > A:S.append(A >> 6 | 192)else:if 55296 == (64512 & A) and v + 1 < len(text) and 56320 == (64512 & ord(text[v + 1])):A = 65536 + ((1023 & A) << 10) + (1023 & ord(text[++v]))S.append(A >> 18 | 240)S.append(A >> 12 & 63 | 128)else:S.append(A >> 12 | 224)S.append(A >> 6 & 63 | 128)S.append(63 & A | 128)p = mF = "+-a^+6"D = "+-3^+b+-f"for b in range(len(S)):p += S[b]p = n(p, F)p = n(p, D)p ^= sif p < 0:p = (2147483647 & p) + 2147483648p %= 1e6return f"{int(p)}." + str(int(p) ^ m)def n(r, o):t = 0while t < len(o) - 2:a = ord(o[t + 2])a = a - 87 if a >= ord('a') else int(o[t + 2])a = r >> a if o[t + 1] == '+' else r << ar = r + a & 4294967295 if o[t] == '+' else r ^ at += 3return rdef calculate_sign(text):return translate_encrypt(text)if __name__ == '__main__':# text_to_translate = '你好世界'# sign = calculate_sign(text_to_translate)# print(sign)print(fanyi('苹果'))

这篇关于pyexecjs原生js加密算法逆向的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/635145

相关文章

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Node.js net模块的使用示例

《Node.jsnet模块的使用示例》本文主要介绍了Node.jsnet模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下... 目录简介引入 net 模块核心概念TCP (传输控制协议)Socket服务器TCP 服务器创建基本服务器服务器配置选项服

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

JS 实现复制到剪贴板的几种方式小结

《JS实现复制到剪贴板的几种方式小结》本文主要介绍了JS实现复制到剪贴板的几种方式小结,包括ClipboardAPI和document.execCommand这两种方法,具有一定的参考价值,感兴趣的... 目录一、Clipboard API相关属性方法二、document.execCommand优点:缺点:

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用