吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3740|回复: 28
收起左侧

[Web逆向] 【web逆向】南京某学院登录接口分析

  [复制链接]
wuye4 发表于 2024-5-1 13:51
本帖最后由 wuye4 于 2024-5-1 14:02 编辑

声明

本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关。本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除。

目标地址: aHR0cHM6Ly9pLm5qY2l0LmNuL0VJUC91c2VyL2luZGV4Lmh0bQ==

一、找接口

1.tickets接口

image-20240428165810963.png

登录之后发现密码被加密了打一个XHR断点包含v1/tickets,重新登录后发现密码已经是被加密的状态了,我们需要找到未被加密的状态。

image-20240428171108959.png

然后我们根据调用栈堆找一下,发现下面这个函数有点意思,有个v1/tickets还有下面的参数与我们要请求的参数一致,初步怀疑是这个,打个断点试试。

image-20240428171749167.png

断点之后,证实下面这个函数就是对原密码进行加密的,现在可以开始扣js代码了。

image-20240428172350465.png

先把O函数扣下来,删掉多余的部分,然后依次补齐未知参数。(h是我们需要的值)
O = function (e, t, a, i) {
    var f = n(5);
    e = e.replace(/(^\s*)|(\s*$)/g, ""),
        t = t.replace(/(^\s*)|(\s*$)/g, "");
    var h = "";
    if (!i) {
        n.i(p.a)(131);
        var w = n.i(p.b)(r.a.public_exponent, "", r.a.modulus);
        h = n.i(p.c)(w, t)
    }
    return h
}
接下来看n(5),由于是webpack打包,扣出来,导出加载器。把n(5)替换成wuye4(5), 运行后就会打印加载5这个模块,然后扣模块5.
var window = global;
var wuye4;
!function (e) {
    function t(n) {
        if (r[n])
            return r[n].exports;
        var o = r[n] = {
            i: n,
            l: !1,
            exports: {}
        };
        # 这里输出缺少啥模块
        console.log("加载" + n)
        return e[n].call(o.exports, o, o.exports, t),
            o.l = !0,
            o.exports
    }
        #全局变量导出加载器
    wuye4 = t;
    var n = window.webpackJsonp;
    window.webpackJsonp = function (r, i, a) {
        for (var c, u, l, s = 0, f = []; s < r.length; s++)
            u = r,
            o && f.push(o[0]),
                o = 0;
        for (c in i)
            Object.prototype.hasOwnProperty.call(i, c) && (e[c] = i[c]);
        for (n && n(r, i, a); f.length;)
            f.shift()();
        if (a)
            for (s = 0; s < a.length; s++)
                l = t(t.s = a);
        return l
    }
    ;
    var r = {}
        , o = {
        1: 0
    };
    t.e = function (e) {
        function n() {
            c.onerror = c.onload = null,
                clearTimeout(u);
            var t = o[e];
            0 !== t && (t && t[1](new Error("Loading chunk " + e + " failed.")),
                o[e] = void 0)
        }

        var r = o[e];
        if (0 === r)
            return new Promise(function (e) {
                    e()
                }
            );
        if (r)
            return r[2];
        var i = new Promise(function (t, n) {
                r = o[e] = [t, n]
            }
        );
        r[2] = i;
        var a = document.getElementsByTagName("head")[0]
            , c = document.createElement("script");
        c.type = "text/javascript",
            c.charset = "utf-8",
            c.async = !0,
            c.timeout = 12e4,
        t.nc && c.setAttribute("nonce", t.nc),
            c.src = t.p + "" + e + "." + {
                0: "36dfd3304064452be2de"
            }[e] + ".js";
        var u = setTimeout(n, 12e4);
        return c.onerror = c.onload = n,
            a.appendChild(c),
            i
    }
        ,
        t.m = e,
        t.c = r,
        t.i = function (e) {
            return e
        }
        ,
        t.d = function (e, n, r) {
            t.o(e, n) || Object.defineProperty(e, n, {
                configurable: !1,
                enumerable: !0,
                get: r
            })
        }
        ,
        t.n = function (e) {
            var n = e && e.__esModule ? function () {
                        return e.default
                    }
                    : function () {
                        return e
                    }
            ;
            return t.d(n, "a", n),
                n
        }
        ,
        t.o = function (e, t) {
            return Object.prototype.hasOwnProperty.call(e, t)
        }
        ,
        t.p = "/",
        t.oe = function (e) {
            throw console.error(e),
                e
        }
}({
     "5": function (e, t, n) {
        "use strict";
        t.decode = t.parse = n(1212),
            t.encode = t.stringify = n(1213)
    },
})
找到这个数组里面的5把函数扣出来.一共要加载5、加载1212、加载1213、加载34、四个模块,剩下的自己扣.不想扣的话,可以把整个js文件都复制出来.

image-20240428174959272.png

接着看p参数搜索一下发现就是n(34)替换过去

! image-20240428175840740.png

r.a.public_exponent 加密参数固定值

image-20240428180122205.png

r.a.modulus 加密参数固定值

image-20240428180149446.png

替换函数最终如下,就可以输出加密密码。
O = function (e, t, a, i) {
    var f = wuye4(5);
    e = e.replace(/(^\s*)|(\s*$)/g, ""),
        t = t.replace(/(^\s*)|(\s*$)/g, "");
    var h = "";
    if (!i) {
        wuye4.i(wuye4(34).a)(131);
        var w = wuye4.i(wuye4(34).b)("010001", "", '00b5eeb166e069920e80bebd1fea4829d3d1f3216f2aabe79b6c47a3c18dcee5fd22c2e7ac519cab59198ece036dcf289ea8201e2a0b9ded307f8fb704136eaeb670286f5ad44e691005ba9ea5af04ada5367cd724b5a26fdb5120cc95b6431604bd219c6b7d83a6f8f24b43918ea988a76f93c333aa5a20991493d4eb1117e7b1');
        h = wuye4.i(wuye4(34).c)(w, t)
    }
    return h
}

2.TGT接口

请求1.tickets接口后会响应 TGT-开头的值,接着请求2.TGT接口会响应一个ST-开头的值

image-20240428170250195.png

3.ST接口

把上面ST-开头的值传到这里,请求成功后,就算登陆成功了。

image-20240428170359035.png

二、效果图

image-20240428181150988.png

image-20240428181214545.png

三、扩展(实现查询个人成绩)

点查询个人成绩,进入到教务系统。

image-20240501122449805.png

登录教务系统,把下面的service 替换成上面的url,然后拿到ST开头的值。

image-20240501123817731.png

然后请求这个接口,最后会重定向到学生成绩查询页面。

image-20240501124113186.png

最后调用查询成绩接口。

image-20240501124320922.png

效果如下

image-20240501132328218.png

四、把成绩推送到微信

使用pushplus

628df2a54c8f4afa82f70ac8bdfbb29.jpg

五、代码实现

njcit1副本.zip (6.74 KB, 下载次数: 25) ">

免费评分

参与人数 12威望 +1 吾爱币 +32 热心值 +12 收起 理由
笙若 + 1 + 1 谢谢@Thanks!
Yangzaipython + 1 用心讨论,共获提升!
YQYuan + 1 + 1 谢谢@Thanks!
smile1110 + 3 + 1 热心回复!
qin15528 + 1 + 1 用心讨论,共获提升!
SVIP9大会员 + 1 + 1 感谢您的宝贵建议,我们会努力争取做得更好!
hazy1k + 1 + 1 我很赞同!
涛之雨 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
timeni + 1 + 1 用心讨论,共获提升!
铭焱 + 1 + 1 谢谢@Thanks!
撑一把纸伞 + 1 + 1 用心讨论,共获提升!
FitContent + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| wuye4 发表于 2024-5-2 09:54
有其它想要逆向,或者分析的可以留言,或者私信我。
 楼主| wuye4 发表于 2024-5-2 21:05
SVIP9大会员 发表于 2024-5-2 13:00
楼主,看你的每一步都挺清晰的,是否有什么教程能推荐我们看看,我只会扣一些简单的加密,有时候断点断不对 ...

b站上有,搜索一下web逆向或者js逆向,巩固一下基础,然后多找网站练习,有时候断点不对是很正常的,都不是一下就可以成功的,也要不断试错。
SVIP9大会员 发表于 2024-5-2 13:00
楼主,看你的每一步都挺清晰的,是否有什么教程能推荐我们看看,我只会扣一些简单的加密,有时候断点断不对,需要费很大的劲,想知道楼主怎么学习的?
dork 发表于 2024-5-4 22:39
220405101同学,请来我办公室一趟
tomatojam99 发表于 2024-5-22 11:24
学习了,感谢分享
qingshuiyixin 发表于 2024-5-22 11:03
学习了,逆向思路很清晰。
李玉风我爱你 发表于 2024-5-6 20:06
[Python] 纯文本查看 复制代码
import rsa

m = 'b5eeb166e069920e80bebd1fea4829d3d1f3216f2aabe79b6c47a3c18dcee5fd22c2e7ac519cab59198ece036dcf289ea8201e2a0b9ded307f8fb704136eaeb670286f5ad44e691005ba9ea5af04ada5367cd724b5a26fdb5120cc95b6431604bd219c6b7d83a6f8f24b43918ea988a76f93c333aa5a20991493d4eb1117e7b1'
e = '10001'
message = '123456'

class Encrypt(object):
    def __init__(self, e, m):
        self.e = e
        self.m = m

    def encrypt(self, message):
        mm = int(self.m, 16)
        ee = int(self.e, 16)
        rsa_pubkey = rsa.PublicKey(mm, ee)
        crypto = self._encrypt(message.encode(), rsa_pubkey)
        return crypto.hex()

    def _pad_for_encryption(self, message, target_length):
        message = message[::-1]
        max_msglength = target_length - 11
        msglength = len(message)

        padding = b''
        padding_length = target_length - msglength - 3

        for i in range(padding_length):
            padding += b'\x00'

        return b''.join([b'\x00\x00', padding, b'\x00', message])

    def _encrypt(self, message, pub_key):
        keylength = rsa.common.byte_size(pub_key.n)
        padded = self._pad_for_encryption(message, keylength)

        payload = rsa.transform.bytes2int(padded)
        encrypted = rsa.core.encrypt_int(payload, pub_key.e, pub_key.n)
        block = rsa.transform.int2bytes(encrypted, keylength)

        return block


en = Encrypt(e, m)
print(en.encrypt(message))
Yangzaipython 发表于 2024-5-6 16:54

学习一下,感谢分享
anadcdwj 发表于 2024-5-6 01:50
初出茅庐,感觉还是有几个步骤需要花点时间理解,但真的很详细,谢谢楼主
amwquhwqas128 发表于 2024-5-4 19:50
wuye4 发表于 2024-5-3 21:06
肯定是网站的问题

这样是不是 说明这个网站不能用hook方式啦?
zf19871001 发表于 2024-5-4 17:58
分析找到那个断点的位置是挺费劲的啊
nicksean 发表于 2024-5-4 12:32
学习一下,感谢分享
FCGkitty 发表于 2024-5-4 12:13
wuye4 发表于 2024-5-2 09:54
有其它想要逆向,或者分析的可以留言,或者私信我。

铁子,你又忘记一个坑了。。。JS扣的好仔细。。我都是把整个JS搬过来的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 01:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表