【JS逆向】珍X网登陆密码RSA 加密

注意:文章内容仅用于学习和技术交流,如有侵权请联系我删除。


学者应洁身自好,切勿做出违法的事情,旨在提供逆向思路。

➣➣欢迎关注本人微信公众号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
});

完事~~~收工~~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值