js逆向-某敏感网站登录参数分析

news2024/11/20 2:24:09

声明

本文仅供学习参考,如有侵权可私信本人删除,请勿用于其他途径,违者后果自负!

如果觉得文章对你有所帮助,可以给博主点击关注和收藏哦!

前言

目标网站:aHR0cHM6Ly9tZGZnaGcuNXhwb2lqaHRmLmNvbS9kZWZhdWx0Lmh0bWwjLw==

接口:auth.login

参数分析

进入网站后点击登录,会有一个简单的验证码,输入之后才会提交登录参数。
在这里插入图片描述
可以看到这个参数很长,肉眼也看不懂不知道是什么东西,毫无疑问是进行了加密。

由于之前我已经分析过了网站,所以直接搜索json=即可定位到加密位置。

ps:最近发现在更新了新版本的谷歌后使用F12的搜索很多内容都搜索不到,上网查了查资料。
在这里插入图片描述

然后重启就可以了。

继续回归正题,通过关键字定位后:
在这里插入图片描述

观察代码后分别打上断点,重新触发。

单步调试,执行u函数。
在这里插入图片描述

一个JSON.stringify的功能,console中输出的参数信息密码是进行了加密,还获取了输入的验证码及验证码id,肯定是要拿到后端进行校验。
通过反复调试发现saltedPassword是动态变化的,截图中的盐值也能够看到这一点。

那么现在的需求就比较明确了,首先将输入的明文密码加密,然后再组装成一个对象,进行一堆乱七八糟的计算当做参数提交由后端验证。

首先查看密码的加密算法,搜索一下关键字。
在这里插入图片描述

在这里插入图片描述
盐就是当前时间戳,token是密文密码,进行了sha1加盐的双重哈希。(算法见下文)
搞清楚了密码的算法后,就到了登陆提交的表单参数了,其中id值为:
在这里插入图片描述

比较简单,没什么说的。
跟了一遍u函数发现还是一个JSON.stringify的操作。
继续就到了加密表单数据的位置:

E = "json=" + Object(m.a)(l.a.stringify(_).slice(5)) + "|" + t.id;

剩下的就是单步然后把代码抠出来,直接放在最下面了。

算法还原

直接把代码拉下来就可以使用

var r = "="
    , i = 8;

function a(t, e) {
    t[e >> 5] |= 128 << 24 - e % 32,
        t[15 + (e + 64 >> 9 << 4)] = e;
    for (var n = Array(80), r = 1732584193, i = -271733879, a = -1732584194, c = 271733878, _ = -1009589776, l = 0; l < t.length; l += 16) {
        for (var h = r, f = i, g = a, p = c, m = _, y = 0; y < 80; y++) {
            n[y] = y < 16 ? t[l + y] : d(n[y - 3] ^ n[y - 8] ^ n[y - 14] ^ n[y - 16], 1);
            var E = u(u(d(r, 5), o(y, i, a, c)), u(u(_, n[y]), s(y)));
            _ = c,
                c = a,
                a = d(i, 30),
                i = r,
                r = E
        }
        r = u(r, h),
            i = u(i, f),
            a = u(a, g),
            c = u(c, p),
            _ = u(_, m)
    }
    return Array(r, i, a, c, _)
}

function o(t, e, n, r) {
    return t < 20 ? e & n | ~e & r : t < 40 ? e ^ n ^ r : t < 60 ? e & n | e & r | n & r : e ^ n ^ r
}

function s(t) {
    return t < 20 ? 1518500249 : t < 40 ? 1859775393 : t < 60 ? -1894007588 : -899497514
}

function u(t, e) {
    var n = (65535 & t) + (65535 & e);
    return (t >> 16) + (e >> 16) + (n >> 16) << 16 | 65535 & n
}

function d(t, e) {
    return t << e | t >>> 32 - e
}

function c(t) {
    for (var e = Array(), n = (1 << i) - 1, r = 0; r < t.length * i; r += i)
        e[r >> 5] |= (t.charCodeAt(r / i) & n) << 32 - i - r % 32;
    return e
}

function _(t) {
    for (var e = "", n = 0; n < 4 * t.length; n += 3)
        for (var i = (t[n >> 2] >> 8 * (3 - n % 4) & 255) << 16 | (t[n + 1 >> 2] >> 8 * (3 - (n + 1) % 4) & 255) << 8 | t[n + 2 >> 2] >> 8 * (3 - (n + 2) % 4) & 255, a = 0; a < 4; a++)
            8 * n + 6 * a > 32 * t.length ? e += r : e += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(i >> 6 * (3 - a) & 63);
    return e
}

var encode = {
    Encode: function () {
        var t = this
            , e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        this.encodeBase64 = function (t) {
            var n, r, i, a, o, s, u, d = "", c = 0;
            for (t = function (t) {
                t = t.replace(/\r\n/g, "\n");
                for (var e = "", n = 0; n < t.length; n++) {
                    var r = t.charCodeAt(n);
                    r < 128 ? e += String.fromCharCode(r) : r > 127 && r < 2048 ? (e += String.fromCharCode(r >> 6 | 192),
                        e += String.fromCharCode(63 & r | 128)) : (e += String.fromCharCode(r >> 12 | 224),
                        e += String.fromCharCode(r >> 6 & 63 | 128),
                        e += String.fromCharCode(63 & r | 128))
                }
                return e
            }(t); c < t.length;)
                a = (n = t.charCodeAt(c++)) >> 2,
                    o = (3 & n) << 4 | (r = t.charCodeAt(c++)) >> 4,
                    s = (15 & r) << 2 | (i = t.charCodeAt(c++)) >> 6,
                    u = 63 & i,
                    isNaN(r) ? s = u = 64 : isNaN(i) && (u = 64),
                    d = d + e.charAt(a) + e.charAt(o) + e.charAt(s) + e.charAt(u);
            return d
        },

            this.encodeSha1 = function (t) {
                return _(a(c(e = t), e.length * i));
                var e
            },
            this.encodePsw = function (e) {
                var n = (new Date).getTime();
                return {
                    salt: n,
                    token: t.encodeSha1(t.encodeSha1(e) + n)
                }
            }
    }
};

var myA = new encode.Encode()
result = myA.encodePsw('明文密码')
console.log(result)

生成id代码:

function getIdentity() {
	return (new Date).getTime().toString().slice(2) + "" + Math.floor(900 * Math.random() + 100) + __WEBPACK_IMPORTED_MODULE_13__store__.a.getters.uid // __WEBPACK_IMPORTED_MODULE_13__store__.a.getters.uid = ''
}

l.a.stringify(_)代码:

function u_ (e, n, i, o, a, u, c, f, l, d, h, p) {
   var v = e;
   var s = {
       "delimiter": "&",
       "encode": true,
       "encodeValuesOnly": false,
       "skipNulls": false,
       "strictNullHandling": false,
       encoder:function(t) {
           if (0 === t.length)
               return t;
           for (var e = "string" == typeof t ? t : String(t), n = "", r = 0; r < e.length; ++r) {
               var o = e.charCodeAt(r);
               45 === o || 46 === o || 95 === o || 126 === o || o >= 48 && o <= 57 || o >= 65 && o <= 90 || o >= 97 && o <= 122 ? n += e.charAt(r) : o < 128 ? n += i[o] : o < 2048 ? n += i[192 | o >> 6] + i[128 | 63 & o] : o < 55296 || o >= 57344 ? n += i[224 | o >> 12] + i[128 | o >> 6 & 63] + i[128 | 63 & o] : (r += 1,
               o = 65536 + ((1023 & o) << 10 | 1023 & e.charCodeAt(r)),
               n += i[240 | o >> 18] + i[128 | o >> 12 & 63] + i[128 | o >> 6 & 63] + i[128 | 63 & o])
           }
           return n
       },
       serializeDate: function(t) {
           return a.call(t)
       }
   }
   if ("function" == typeof c)
       v = c(n, v);
   else if (v instanceof Date)
       v = d(v);
   else if (null === v) {
       if (o)
           return u && !p ? u(n, s.encoder) : n;
       v = ""
   }
   if ("string" == typeof v || "number" == typeof v || "boolean" == typeof v || r.isBuffer(v))
       return u ? [h(p ? n : u(n, s.encoder)) + "=" + h(u(v, s.encoder))] : [h(n) + "=" + h(String(v))];
   var m, g = [];
   if (void 0 === v)
       return g;
   if (Array.isArray(c))
       m = c;
   else {
       var y = Object.keys(v);
       m = f ? y.sort(f) : y
   }
   for (var w = 0; w < m.length; ++w) {
       var b = m[w];
       a && null === v[b] || (g = Array.isArray(v) ? g.concat(t(v[b], i(n, b), i, o, a, u, c, f, l, d, h, p)) : g.concat(t(v[b], n + (l ? "." + b : "[" + b + "]"), i, o, a, u, c, f, l, d, h, p)))
   }
   return g
};
array_i = function() {
   for (var t = [], e = 0; e < 256; ++e)
       t.push("%" + ((e < 16 ? "0" : "") + e.toString(16)).toUpperCase());
   return t
}();
function l_a_stringify(t, e) {
   var i = {
       default: "RFC3986",
       formatters: {
           RFC1738: function(t) {
               return r.call(t, i, "+")
           },
           RFC3986: function(t) {
               return t
           }
       },
       RFC1738: "RFC1738",
       RFC3986: "RFC3986"
   };
   
   var o ={
       brackets: function(t) {
           return t + "[]"
       },
       indices: function(t, e) {
           return t + "[" + e + "]"
       },
       repeat: function(t) {
           return t
       }
   }
   var a = Date.prototype.toISOString;
   var s = {
       "delimiter": "&",
       "encode": true,
       "encodeValuesOnly": false,
       "skipNulls": false,
       "strictNullHandling": false,
       encoder:function(t) {
           if (0 === t.length)
               return t;
           for (var e = "string" == typeof t ? t : String(t), n = "", r = 0; r < e.length; ++r) {
               var o = e.charCodeAt(r);
               45 === o || 46 === o || 95 === o || 126 === o || o >= 48 && o <= 57 || o >= 65 && o <= 90 || o >= 97 && o <= 122 ? n += e.charAt(r) : o < 128 ? n += array_i[o] : o < 2048 ? n += array_i[192 | o >> 6] + array_i[128 | 63 & o] : o < 55296 || o >= 57344 ? n += array_i[224 | o >> 12] + array_i[128 | o >> 6 & 63] + array_i[128 | 63 & o] : (r += 1,
               o = 65536 + ((1023 & o) << 10 | 1023 & e.charCodeAt(r)),
               n += array_i[240 | o >> 18] + array_i[128 | o >> 12 & 63] + array_i[128 | o >> 6 & 63] + array_i[128 | 63 & o])
           }
           return n
       },
       serializeDate: function(t) {
           return a.call(t)
       }
   }
   var n = t
     , a = e ? r.assign({}, e) : {};
   if (null !== a.encoder && void 0 !== a.encoder && "function" != typeof a.encoder)
       throw new TypeError("Encoder has to be a function.");
   var c = void 0 === a.delimiter ? s.delimiter : a.delimiter
     , f = "boolean" == typeof a.strictNullHandling ? a.strictNullHandling : s.strictNullHandling
     , l = "boolean" == typeof a.skipNulls ? a.skipNulls : s.skipNulls
     , d = "boolean" == typeof a.encode ? a.encode : s.encode
     , h = "function" == typeof a.encoder ? a.encoder : s.encoder
     , p = "function" == typeof a.sort ? a.sort : null
     , v = void 0 !== a.allowDots && a.allowDots
     , m = "function" == typeof a.serializeDate ? a.serializeDate : s.serializeDate
     , g = "boolean" == typeof a.encodeValuesOnly ? a.encodeValuesOnly : s.encodeValuesOnly;
   if (void 0 === a.format)
       a.format = i.default;
   else if (!Object.prototype.hasOwnProperty.call(i.formatters, a.format))
       throw new TypeError("Unknown format option provided.");
   var y, w, b = i.formatters[a.format];
   "function" == typeof a.filter ? n = (w = a.filter)("", n) : Array.isArray(a.filter) && (y = w = a.filter);
   var _, D = [];
   if ("object" != typeof n || null === n)
       return "";
   _ = a.arrayFormat in o ? a.arrayFormat : "indices"in a ? a.indices ? "indices" : "repeat" : "indices";
   var S = o[_];
   y || (y = Object.keys(n)),
   p && y.sort(p);
   for (var M = 0; M < y.length; ++M) {
       var x = y[M];
       l && null === n[x] || (D = D.concat(u_(n[x], x, S, f, l, d ? h : null, w, p, v, m, b, g)))
   }
   var O = D.join(c)
     , k = !0 === a.addQueryPrefix ? "?" : "";
   return O.length > 0 ? k + O : ""
}

var _ = {
   "json": "{\"id\":\"00914528435406\",\"jsonrpc\":\"2.0\",\"method\":\"auth.login\",\"params\":{\"sn\":\"wy12\",\"loginId\":\"手机号\",\"saltedPassword\":\"密码\",\"salt\":盐值,\"captchaKey\":\"3763286221\",\"captchaCode\":\"5864\",\"withAuth\":\"1\",\"withProfile\":\"1\",\"withBalance\":\"1\",\"terminal\":1,\"host\":\"mdfghg.5xpoijhtf.com\",\"fingerOSModel\":\"Chrome 117.0.0.0 | Windows 10\",\"ztsLang\":\"zh\"}}"
}
console.log(l_a_stringify(_)) 

Object(m.a)代码:

function object_m_a(t) {
            var e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
            function n(t, e) {
                return Math.floor(Math.random() * (e - t)) + t
            }
            var r = function(t) {
                for (var r = Array(t), i = e.slice(0, 52), a = 0; a < r.length; a++)
                    r[a] = i[n(0, i.length)];
                return r.join("")
            }(24)
              , i = function(t) {
                var n, r, i, a, o, s, u, d = "", c = 0;
                for (t = function(t) {
                    t = t.replace(/\r\n/g, "\n");
                    for (var e = "", n = 0; n < t.length; n++) {
                        var r = t.charCodeAt(n);
                        r < 128 ? e += String.fromCharCode(r) : r > 127 && r < 2048 ? (e += String.fromCharCode(r >> 6 | 192),
                        e += String.fromCharCode(63 & r | 128)) : (e += String.fromCharCode(r >> 12 | 224),
                        e += String.fromCharCode(r >> 6 & 63 | 128),
                        e += String.fromCharCode(63 & r | 128))
                    }
                    return e
                }(t); c < t.length; )
                    a = (n = t.charCodeAt(c++)) >> 2,
                    o = (3 & n) << 4 | (r = t.charCodeAt(c++)) >> 4,
                    s = (15 & r) << 2 | (i = t.charCodeAt(c++)) >> 6,
                    u = 63 & i,
                    isNaN(r) ? s = u = 64 : isNaN(i) && (u = 64),
                    d = d + e.charAt(a) + e.charAt(o) + e.charAt(s) + e.charAt(u);
                return d
            }(t);
            return "pwv|13|" + function(t, e) {
                for (var n = "", r = 0, i = 0; i < e.length; i++) {
                    var a = t.charCodeAt(r % t.length)
                      , o = e.charCodeAt(i)
                      , s = o;
                    o >= 65 && o <= 90 && (a >= 65 && a <= 90 && (s = (a - 65 + (o - 65)) % 26 + 65),
                    a >= 97 && a <= 122 && (s = (a - 97 + (o - 65)) % 26 + 65),
                    r++),
                    o >= 97 && o <= 122 && (a >= 65 && a <= 90 && (s = (a - 65 + (o - 97)) % 26 + 97),
                    a >= 97 && a <= 122 && (s = (a - 97 + (o - 97)) % 26 + 97),
                    r++),
                    n += String.fromCharCode(s)
                }
                return n
            }(r + "wxfEZdkAYYyBqbnMN", i) + "|" + r
        }

总结

此网站内容还是比较简单,我这里分析的比较乱,自己分析的话可以参考一下。
另外,登陆的验证码可以使用python的ddddocr,然后把整个流程串通起来就可以实现登陆了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LED面板显示屏驱动芯片

一、基本概述 TM1638是一种带键盘扫描接口的LED&#xff08;发光二极管显示器&#xff09;驱动控制专用IC,内部集成有MCU数字接口、数据锁存器、LED驱动、键盘扫描等电路。本产品质量可靠、稳定性好、抗干扰能力强。 二、主要应用场合 主要适用于家电设备(智能热水器、微波炉…

leetcode刷题:17.电话号码的字母组合

leetcode原题网页 题目描述&#xff1a;给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 思路&#xff1a;使用vector&#x…

基于51单片机超市快递寄存自动柜设计源程序

一、系统方案 1、本设计采用这51单片机作为主控器。 2、存包&#xff0c;GSM短信取件码。 3、液晶1620显示。 4、矩阵键盘输入取件码&#xff0c;完成取包。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 /******************************…

#BUG SHOW# 深挖一个6年前的老“bug”

引言 最近参与了一个业务迁移的项目&#xff0c;需要把站点A迁移到站点B。不同的站点拥有各自独立的服务和数据库&#xff0c;可以说是毫无关联。为了兼容迁移过程中的存在的一部分特殊交易数据&#xff08;正向[支付]交易在站点A&#xff0c;但逆向[退款]操作在站点B操作&…

Oracle 最终抛弃了 Sun !

随着 Solaris 团队的彻底完蛋&#xff0c;看起来 Sun 微系统公司最终连块骨头都没剩下。 来自前 Sun 社区的消息表明&#xff0c;一月份的传闻&#xff08;Oracle 裁员 450 人&#xff09;成为了现实&#xff0c;上周五&#xff0c;Oracle 裁掉了 Solaris 和 SPARC 团队的核心员…

交换机的VRRP主备配置例子

拓朴如下&#xff1a; 主要配置如下&#xff1a; [S1] vlan batch 10 20 # interface Vlanif10ip address 10.1.1.1 255.255.255.0vrrp vrid 1 virtual-ip 10.1.1.254vrrp vrid 1 priority 200vrrp vrid 1 preempt-mode timer delay 20 # interface Vlanif20ip address 13.1.1…

QT visual stdio加载动态库报错126问题

报错126是找不到指定的模块 QT 查看构建目录&#xff0c;将依赖的动态库放到该目录下即可成功 visual stdio将依赖的动态库放到运行目录 在vs中使用导出类的动态库时&#xff0c;不但需要将对应的.dll放到对应的目录下&#xff0c;还需要将该动态库对应的.lib添加到如下配置才…

ChatGLM-6B下载安装

ChatGLM-6B下载安装 项目指向 想把模型下载本地微调 通过官网指引需要先下载git-lfs #Linux 下载安装 curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash sudo apt-get install git-lfs git lfs install如果是docker中的虚拟机…

物流单打印模板下载,佳易王物流托运单打印软件

物流单打印模板下载&#xff0c;佳易王物流托运单打印软件 上图是常用的物流单打印模板&#xff0c;佳易王物流单打印软件打印格式可以根据需要定制更改。 软件特色&#xff1a; 1、功能实用&#xff0c;操作简单&#xff0c;不会电脑也会操作&#xff0c;软件免安装&#xff…

Halcon [fill_up_shape],[close_circle],[dilation_circle]和[shape_trans]图像处理时填充区别

文章目录 文章专栏前言两者的区别fill_up_shapeshape_transclose_circledilation_circle 总结 文章专栏 我的Halcon开发 CSDN专栏 前言 本文用的案例是&#xff1a;Example: %HALCONEXAMPLES%/hdevelop/Applications/Completeness-Check/ball.hdev 两者的区别 [shape_trans]是…

【LLM】chatglm3的agent应用和微调实践

note 知识库和微调并不是冲突的&#xff0c;它们是两种相辅相成的行业解决方案。开发者可以同时使用两种方案来优化模型。例如&#xff1a; 使用微调的技术微调ChatGLM3-6B大模型模拟客服的回答的语气和基础的客服思维。接着&#xff0c;外挂知识库将最新的问答数据外挂给Chat…

vue2-006——使用脚手架搭建vue2项目+项目结构分析

一、创建项目&#xff1a;vue create 项目名 D:\EnyiWang\Documents\myStudy\vue>vue create vue_testVue CLI v5.0.8 ? Please pick a preset: Default ([Vue 2] babel, eslint)Vue CLI v5.0.8 ✨ Creating project in D:\EnyiWang\Documents\myStudy\vue\vue_test. &am…

批量按顺序1、2、3...重命名所有文件夹里的文件

最新&#xff1a; 最快方法&#xff1a;先用这个教程http://文件重命名1,2......nhttps://jingyan.baidu.com/article/495ba841281b7079b20ede2c.html再用这个教程去空格&#xff1a;利用批处理去掉文件名中的空格-百度经验 (baidu.com) 以下为原回答 注意文件名有空格会失败…

张弛声音变现课,惊悚电影配音篇

在提供惊悚片的声音配音服务时&#xff0c;配音员旨在制造一种让观众的心率加快、情绪紧张的气氛。惊悚片侧重于心理层面的紧张和预期的恐怖&#xff0c;声音在塑造这种心理效应中起到了至关重要的作用。演员需通过对声音的精细雕琢和调整来强化电影的悬念和紧迫感。以下是为惊…

SIM卡结构及上电流程详解

SIM卡结构及上电流程详解 1. sim卡概述1.1 什么是SIM卡1.2 Sim卡的作用 2. Sim卡的主要功能2.1存储数据2.2 PIN码保护2.3 用户身份鉴权2.4 Sim卡中的保密算法及密钥2.5 SIM卡的类型2.6 Sim卡物理接口2.7 SIM卡内部结构2.8 SIM卡文件结构2.9 常用的文件操作2.9.1 常用的有如下操…

Java基础(第九期):Java中的集合 ArrayList 集合的增删改查 Java实现学生信息管理系统

⚠️Java基础专栏 文章目录 ⚠ Java基础最后一期&#xff08;第九期&#xff09;到此结束 Java中的集合一、什么是集合二、ArrayList2.1 ArrayList介绍2.2ArrayList使用2.3 ArrayList添加add&#xff08;&#xff09;方法add&#xff08;index&#xff0c;E element&#xff0…

《微信小程序开发从入门到实战》学习二十九

3.4 开发参与投票页面 3.4.4 使用label组件扩大单击区域 radio组件的单击区域很小&#xff0c;只有文字左侧的圆圈可以点击&#xff0c;实际使用者一般会期望点击文字也可以选中选项&#xff0c;用label组件包含radio组件&#xff0c;就可以实现点击文字也可以选项。 label组…

基于WSL2+Docker+VScode搭建机器学习(深度学习)开发环境

基于WSL2DockerVScode搭建机器学习(深度学习)开发环境 内容概述&#xff1a;由于最近配发了新的工作电脑但不想装双系统&#xff0c;因此通过本博文来记录基于Windows子系统WSLDocker搭建机器学习与深度学习开发环境的流程步骤&#xff0c;同时记录该过程中所遇到的相关问题及解…

上新!2023年汉字小达人市级比赛在线模拟题增加2个刷题试卷

各位小学三年级到五年级的上海学霸孩子们&#xff0c;刚刚结束了上海小学生古诗文大会的复赛&#xff0c;就紧锣密鼓地全身心投入到上海小学生汉字小达人的市级比赛的备赛中了。 为了助各位孩子一臂之力&#xff0c;我把在线模拟题进行了更新&#xff0c;新增了两个可以刷题的试…

安卓用SQLite数据库存储数据

什么是SQLite&#xff1f; SQLite是安卓中的轻量级内置数据库&#xff0c;不需要设置用户名和密码就可以使用。资源占用较少&#xff0c;运算速度也比较快。 SQLite支持&#xff1a;null&#xff08;空&#xff09;、integer&#xff08;整形&#xff09;、real&#xff08;小…