注意:文章内容仅用于学习和技术交流,如有侵权请联系我删除。
学者应洁身自好,切勿做出违法的事情,旨在提供逆向思路。
➣➣欢迎关注本人微信公众号:Anonymous NoteBook➣➣
分享好玩有趣的网络资源&软件工具~
分享各种技术性PDF资源/付费查询PDF资源~
分享各种编程语言、开发技术、分布式事务、大数据与云计算技术~
分享有关网络爬虫(Web爬虫逆向 | 安卓逆向)案例、数据挖掘、技术心得等~
aHR0cHM6Ly93d3cuemhlbmFpLmNvbS9uL2xvZ2lu
问题分析:
通过登陆界面,查看加密字段:
password 为加密字段,猜测为rsa加密,登陆时会有行为检测,其余加密字段均为xx验证的加密字段,此次分析主要以password加密字段为主。
逆向分析:
老规矩, 全局搜索password字段,出现两条内容,并且有一条包含login关键词,点进去看下:
动态调试看下结果:
是的,没错,这里正是password加密的入口,观察下加密函数,发现为匿名函数,跟进去:
哦吼吼。。。看到有 setPublicKey 函数,确实为rsa加密没错。
参数 t 和 n 均已定义好了,e是我们传进来的明文密码,这里实例化了JSEncrypt对象,然后设置公钥,最后对明文字符串进行加密。
我们发现JSEncrypt真实调用的是xt:
对明文字符串进行加密的方法是xt.encrypt,我们跟下 xt(t):
此时我们来到了一个名为 jsencrypt.js 文件里,通过观察得知,此文件就是加密的逻辑所在。
很简单,直接拷贝此文件到本地,稍微修改下,运行调试。
哎呀~~~~ 出错了....
如果你未补全变量的情况下,直接运行js文件,肯定是要报错的。
缺什么我们补上就好了。
在拷贝下来的 jsencrypt.js 文件的开头,我们补上全局变量:
【这里我补全了所有变量,有的变量你可能不需要定义,只补你需要的就好。】
这时,我们再重新运行下看看:
运行正常。
// jsencrypt.js
/*! JSEncrypt v2.3.1 | https://npmcdn.com/jsencrypt@2.3.1/LICENSE.txt */
var window = global;
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
var document = dom.window.document;
window.document = document;
var navigator = {
appName: "Netscape",
appVersion: "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36",
cookieEnabled: true,
deviceMemory: 8,
doNotTrack: null,
hardwareConcurrency: 4,
language: "zh-CN",
languages: ["zh-CN", "zh"],
maxTouchPoints: 0,
onLine: true,
platform: "Win32",
product: "Gecko",
productSub: "20030107",
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36",
vendor: "Google Inc.",
vendorSub: "",
};
var location = {
hash: "",
host: "www.xxx.com",
hostname: "www.xxx.com",
href: "https://www.xxx.com",
origin: "https://www.xxx.com",
pathname: "/",
port: "",
protocol: "https:",
search: "",
};
var screen = {
availHeight: 1040,
availLeft: 0,
availTop: 0,
availWidth: 1920,
colorDepth: 24,
height: 1080,
pixelDepth: 24,
width: 1920,
};
!function(t, e) {
"function" == typeof define && define.amd ? define(["exports"], e) : e("object" == typeof exports && "string" != typeof exports.nodeName ? module.exports : t)
}(this, function(t) {
function e(t, e, r) {
null != t && ("number" == typeof t ? this.fromNumber(t, e, r) : null == e && "string" != typeof t ? this.fromString(t, 256) : this.fromString(t, e))
}
function r() {
return new e(null)
}
function s(t, e, r, s, i, n) {
for (; --n >= 0; ) {
var o = e * this[t++] + r[s] + i;
i = Math.floor(o / 67108864),
r[s++] = 67108863 & o
}
return i
}
function i(t, e, r, s, i, n) {
for (var o = 32767 & e, h = e >> 15; --n >= 0; ) {
var a = 32767 & this[t]
, u = this[t++] >> 15
, p = h * a + u * o;
a = o * a + ((32767 & p) << 15) + r[s] + (1073741823 & i),
i = (a >>> 30) + (p >>> 15) + h * u + (i >>> 30),
r[s++] = 1073741823 & a
}
return i
}
function n(t, e, r, s, i, n) {
for (var o = 16383 & e, h = e >> 14; --n >= 0; ) {
var a = 16383 & this[t]
, u = this[t++] >> 14
, p = h * a + u * o;
a = o * a + ((16383 & p) << 14) + r[s] + i,
i = (a >> 28) + (p >> 14) + h * u,
r[s++] = 268435455 & a
}
return i
}
function o(t) {
return pt.charAt(t)
}
function h(t, e) {
var r = ct[t.charCodeAt(e)];
return null == r ? -1 : r
}
function a(t) {
for (var e = this.t - 1; e >= 0; --e)
t[e] = this[e];
t.t = this.t,
t.s = this.s
}
function u(t) {
this.t = 1,
this.s = t < 0 ? -1 : 0,
t > 0 ? this[0] = t : t < -1 ? this[0] = t + this.DV : this.t = 0
}
function p(t) {
var e = r();
return e.fromInt(t),
e
}
......
// 此处省略了N行代码
......
var xt = function(t) {
t = t || {},
this.default_key_size = parseInt(t.default_key_size) || 1024,
this.default_public_exponent = t.default_public_exponent || "010001",
this.log = t.log || !1,
this.key = null
};
xt.prototype.setKey = function(t) {
this.log && this.key && console.warn("A key was already set, overriding existing."),
this.key = new wt(t)
}
,
xt.prototype.setPublicKey = function(t) {
this.setKey(t)
}
,
xt.prototype.encrypt = function(t) {
try {
return st(this.getKey().encrypt(t))
} catch (e) {
return !1
}
}
,
xt.prototype.getKey = function(t) {
if (!this.key) {
if (this.key = new wt,
t && "[object Function]" === {}.toString.call(t))
return void this.key.generateAsync(this.default_key_size, this.default_public_exponent, t);
this.key.generate(this.default_key_size, this.default_public_exponent)
}
return this.key
}
,
xt.version = "2.3.1",
t.JSEncrypt = xt
});