吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 28662|回复: 476
收起左侧

[Web逆向] 【油猴开发指南】实战破解Vue百度文库复制

    [复制链接]
李恒道 发表于 2023-9-6 03:44
本帖最后由 李恒道 于 2023-9-6 15:46 编辑

感谢
在写本文之前
感谢@涛之雨 大佬在我失业期间
为了抚平我内心的伤痛
赠送给我了美国拉斯维加斯豪华七日游(越南中转,需携带配型报告以及身体健康证明)旅游套餐
下周日出发,羡慕死你们

正文
这里我们以一篇百度文库的文章为例
https://wenku.baidu.com/view/5d102fd05322aaea998fcc22bcd126fff7055dfd.html?fr=hp_Database&_wkts_=1688832801754
随便选中一段文字,然后点击复制
001633qnfy8nzvyycxt8vh.png
发现跳转到了百度文库会员购买
001659iqdnldpgzissfnr0.png
那么我们开始分析这个按钮
查看事件监听器,只有一个click事件,跳转进去
到了
[JavaScript] 纯文本查看 复制代码
                e = o._wrapper = function(t) {
                    if (t.target === t.currentTarget || t.timeStamp >= i || t.timeStamp <= 0 || t.target.ownerDocument !== document)
                        return o.apply(this, arguments)
                }

这里基本没什么分支,我们直接在o.apply(this, arguments)打断点
点击复制按钮后断下,往里走,到了
[JavaScript] 纯文本查看 复制代码
            function n() {
                var t = arguments
                  , r = n.fns;
                if (!Array.isArray(r))
                    return Jt(r, null, arguments, e, "v-on handler");
                for (var i = r.slice(), o = 0; o < i.length; o++)
                    Jt(i[o], null, t, e, "v-on handler")
            }

这里我们就是Vue的分发代码了,如果是单个的就只调用一次,如果是多个同样的事件就循环触发事件的回调函数代码
我们这里直接打印n.fns,看到是一个函数,直接跳转进去
发现是一个明显的render模板
002118i1smyzdxfpydttxy.png

我们在t.clickCopy()部分打一个断点继续往里追
找到了
[JavaScript] 纯文本查看 复制代码
                clickCopy: function() {
                    var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "reader";
                    if (a.log.xsend(102222, {
                        position: t
                    }),
                    a.log.xsend(dt, {
                        behavior: ut.CLICK,
                        module: [vt.ReaderPlugin, "copy", t].join("_")
                    }),
                    "remind" === t && !this.canCopy)
                        return this.buyVip("remind");
                    if (this.setVisible(!1),
                    this.setReminderVisible(!1),
                    this.setIsCopyActivated(!0),
                    this.isTaskUser && 1 === this.taskStatus) {
                        var e = this.taskStatus
                          , i = ++e;
                        (0,
                        at.Q)(1, i)
                    }
                },

根据调试我们并走到了
[JavaScript] 纯文本查看 复制代码
                   if (this.setVisible(!1),
                    this.setReminderVisible(!1),
                    this.setIsCopyActivated(!0),
                    this.isTaskUser && 1 === this.taskStatus) {
                        var e = this.taskStatus
                          , i = ++e;
                        (0,
                        at.Q)(1, i)
                    }

所以这里一定有跳转到购买会员页面的代码,我们先从setVisible跟一下看看
走进去到了
[JavaScript] 纯文本查看 复制代码
                n[r] = function() {
                    for (var e = [], n = arguments.length; n--; )
                        e[n] = arguments[n];
                    var r = this.$store.commit;
                    if (t) {
                        var o = S(this.$store, "mapMutations", t);
                        if (!o)
                            return;
                        r = o.context.commit
                    }
                    return "function" == typeof i ? i.apply(this, [r].concat(e)) : r.apply(this.$store, [i].concat(e))
                }

有store字样,疑似是Vuex或者pinia,是vue的全局状态存储
我们看代码可以直接在最后一行打断点
走到了
[JavaScript] 纯文本查看 复制代码
function(n, r, i) {
                        var o = _(n, r, i)
                          , a = o.payload
                          , s = o.options
                          , c = o.type;
                        s && s.root || (c = e + c),
                        t.commit(c, a, s)
                    }

还是在最后一行跟
[JavaScript] 纯文本查看 复制代码
            this.commit = function(t, e, n) {
                return s.call(o, t, e, n)
            }
找到了
[JavaScript] 纯文本查看 复制代码
        p.prototype.commit = function(t, e, n) {
            var r = this
              , i = _(t, e, n)
              , o = i.type
              , a = i.payload
              , s = (i.options,
            {
                type: o,
                payload: a
            })
              , c = this._mutations[o];
            c && (this._withCommit((function() {
                c.forEach((function(t) {
                    t(a)
                }
                ))
            }
            )),
            this._subscribers.slice().forEach((function(t) {
                return t(s, r.state)
            }
            )))
        }

这里c = this._mutations[o];就是对应的store的分发函数了
我们打印一下c跳转进去
发现是
[JavaScript] 纯文本查看 复制代码
(function(e) {
                        n.call(t, r.state, e)
                    }

是一层包裹代码,我们直接打断点,然后进n里
就找到了用户写的分发函数啦!
[JavaScript] 纯文本查看 复制代码
                    setVisible: function(e, t) {
                        e.visible = t
                    },

用同样的方法可以找到全部设置状态的函数,这里我们分别找到了三个,发现没什么特殊的地方,那一定还有其他原因!
我们把目光挪到this.isTaskUser && 1 === this.taskStatus
因为代码是
[JavaScript] 纯文本查看 复制代码
       if (this.setVisible(!1),
                    this.setReminderVisible(!1),
                    this.setIsCopyActivated(!0),
                    this.isTaskUser && 1 === this.taskStatus) {

,表达式前面的都对if没有任何意义,那么缩减代码就是
[JavaScript] 纯文本查看 复制代码
 if (this.isTaskUser && 1 === this.taskStatus) {

我们应该去看isTaskUser和taskStatus!
因为这个是vue的sfc文件生成的代码
我们直接在同文件搜索
[JavaScript] 纯文本查看 复制代码
(0,s.mapState)("visitUserInfo", ["isTaskUser", "taskStatus"]))

这是一个mapState函数,即将全局状态的数据映射到文件中,从而缩减代码的长度
如正常我们获取状态数的数据需要store.visitUserInfo.isTaskUser,而使用mapState缩减了代码长度,只需要使用isTaskUser即可等价于store.visitUserInfo.isTaskUser。
那我们的目标就是触发this.isTaskUser && 1 === this.taskStatus的逻辑
我们可以在(0,s.mapState)("visitUserInfo", ["isTaskUser", "taskStatus"]))上打一个断点,因为这个是组件初始化的时候执行,所以我们需要刷新页面可以发现正常断下了,然后往里走
024112f0qgxh3g3ducu3rg.png
走到了
[JavaScript] 纯文本查看 复制代码
           return function(e, n) {
                return "string" != typeof e ? (n = e,
                e = "") : "/" !== e.charAt(e.length - 1) && (e += "/"),
                t(e, n)
            }

可以看到是兼容性判断,继续看t函数
里面将e进行兼容性处理,然后遍历,挂载到对象n上,所以读取属性是在挂载的函数里
024210oquiwu6w8wu3qwp4.png
我们在var e = this.$store.state打一个断点等待断下
然后输入
[JavaScript] 纯文本查看 复制代码
this.$store.state.visitUserInfo.isTaskUser=true
this.$store.state.visitUserInfo.taskStatus=1

解除这部分的断点,再次触发复制尝试一下
发现流程进去了
024506hkcd4aqn4ge0o00m.png
走进去后唯一比较有意义的代码就是
[JavaScript] 纯文本查看 复制代码
(a.ZP.commit("visitUserInfo/setTaskStatus", e

我们按之前的流程走就可以走到函数里,但是也有一个比较方便的办法,就是直接搜索setTaskStatus,找到了
[JavaScript] 纯文本查看 复制代码
                    setTaskStatus: function(e, t) {
                        e.taskStatus = t
                    },

上面的代码可以看到修改了taskStatus,因为全局状态如果被修改是会在其他地方响应的,所以我们尝试搜索taskStatus,除了我们的代码只有另外一处
[JavaScript] 纯文本查看 复制代码
                  H.Z)({
                            url: "/user/interface/setuserbackground",
                            data: c,
                            method: "POST"
                        })).then((function() {
                            if (n.setThemeDefaultVal(n.viewTheme),
                            n.showBttomTheme = !1,
                            n.isTaskUser && 2 === n.taskStatus) {
                                var t = n.taskStatus
                                  , e = ++t;
                                (0,
                                it.Q)(1, e)
                            }
                        }

其代码是在api"/user/interface/setuserbackground后调用该属性判断,所以我们可以确定该属性几乎没有作用。
那我们的目光只能放在
this.setVisible(!1),
this.setReminderVisible(!1),
this.setIsCopyActivated(!0),
这三个里了,根据之前的经验,我们再进行搜索
> 严谨的说应该按刚才的方式找函数,如果你有经验了可以直接搜索
他们分别修改了
visible
remindVisible
isCopyActivated
所以我们依次再分别搜索这三个遍历看看谁依赖了他们三个,这个时候优先排查搜索结果最少的,我们细致排查后找到了
[JavaScript] 纯文本查看 复制代码
watch: {
     isCopyActivated: function(t) {
        t && !this.canCopy && (a.log.xsend(H, {
            behavior: U.SHOW,
            module: [G.ReaderPlugin, "Copy", "copybtn"].join("_"),
            content: this.selectedTextTrim
        }),
        this.fetchCopyTimes(this.selectedTextTrim, !0))
     },
},

这个函数专门监听了isCopyActivated变量,还检测了this.canCopy是否可以复制,如果不可以复制调用this.fetchCopyTimes(this.selectedTextTrim, !0)),我们进这个函数看看
025951quxu11qebmbd14ub.png
发现明显的clickBuyVipBtn字样和开通vip,很有可能就是这个函数跳转到百度Vip付费页面的!
我们在
[JavaScript] 纯文本查看 复制代码
     isCopyActivated: function(t) {
        ...
        this.fetchCopyTimes(this.selectedTextTrim, !0))
     },

这个函数中还没执行到 this.fetchCopyTimes之前下断点,设置 this.fetchCopyTimes=()=>{},发现没有跳转到付费购买vip页面,说明我们找对了!那问题就变成了canCopy设置为true了
在该js文件搜索canCopy找到了
[JavaScript] 纯文本查看 复制代码
s.mapGetters)("readerPlugin", ["canCopy", "selectedTextTrim", "formatedText"]))

[JavaScript] 纯文本查看 复制代码
    canCopy: function(e, t, n) {
        var r = n.vipInfo
          , o = n.docInfo;
        return !!(null != r && r.isVip || (null == o ? void 0 : o.docBizType) === c.RV.SECRET || (null == o ? void 0 : o.docBizCategory) === c.ll.FREE || null != o && o.hasGot)
    },

获取的是n.vipInfo.isVip,我们在这里打印n,发现n就是vuex的状态树
往上堆栈回溯一层可以看到
[JavaScript] 纯文本查看 复制代码
t._wrappedGetters[e] = function(t) {
    return n(r.state, r.getters, t.state, t.getters)
}

根据对比发现r是局部状态树,t是根状态树,那我们的问题就变成了如何得到根状态树并且设置vipInfo.isVip
说明该变量在vuex中,继续搜索canCopy
查阅vuex源码可知会挂载到$store上,具体分析就不表明了
所以可以写出代码
[JavaScript] 纯文本查看 复制代码
document.querySelector('.header-wrapper').__vue__.$store.state.vipInfo.isVip=true

根据测试可以正常复制
我们成功破解了百度文库复制!

因为写文章到发表具有一定时效性
很多人都说不可以复制

实际是可以复制的
只是默认进去百度文库搞了个AI助手上去,取消编辑就可以回归到正常页面
图片.png 文章其实主要为了抛砖引玉,解决Vue如何从入口函数追踪到正确函数和VUEX的分析方案

随手复制的内容:
就响起了激烈的掌声,原来,超市里正在进行包粽子比赛。我们全
家人都在观看着。最厉害的一个人一分钟包了十一个粽子。看完包粽子比赛后,爸爸说:
“海边今天举行大胃王吃粽子比赛和赛龙舟比赛,我们也去参加呗!”妈妈说:“赛龙舟
比赛那可是许多人一起划的呀,我们就三个人怎么参加呀?”爸爸说:“这次的吃粽子和
划龙舟比赛是经一家三口为单位参加比赛的。”妈妈这下才

免费评分

参与人数 176威望 +2 吾爱币 +268 热心值 +159 收起 理由
Fogkiss + 1 + 1 厉害
hldyl + 1 我很赞同!
ft2470255 + 1 我很赞同!
疯狂の马甲 + 1 + 1 我很赞同!
dandna + 1 用心讨论,共获提升!
gh0815 + 1 + 1 谢谢@Thanks!
tunis + 1 + 1 我很赞同!
Zercher + 1 我很赞同!
jackies + 1 + 1 热心回复!
marsjojo + 1 + 1 鼓励转贴优秀软件安全工具和文档!
doudou110 + 1 + 1 我很赞同!
wangjinhao123 + 1 + 1 热心回复!
yingruan + 1 + 1 热心回复!
Zhai_Yaaa + 1 + 1 谢谢@Thanks!
shiyoufu + 1 + 1 用心讨论,共获提升!
lungzy + 1 + 1 我很赞同!
chuan9 + 1 + 1 谢谢@Thanks!
t43781 + 1 + 1 谢谢@Thanks!
aotm + 1 我很赞同!
H什么的最喜欢了 + 1 + 1 热心回复!
qzdy007 + 1 + 1 用心讨论,共获提升!
bullshit + 1 + 1 谢谢@Thanks!
Lemon1001 + 1 + 1 谢谢@Thanks!
ndtinfo + 1 + 1 谢谢@Thanks!
xtfw99 + 1 + 1 我很赞同!
787821 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
dd185385 + 1 谢谢@Thanks!
ygx666888 + 1 鼓励转贴优秀软件安全工具和文档!
无名小喽啰 + 1 我很赞同!
笙若 + 1 + 1 谢谢@Thanks!
resu + 1 用心讨论,共获提升!
doorgrape + 1 + 1 我很赞同!
infinitymaster + 1 + 1 谢谢@Thanks!
JOJOYUMMY + 1 + 1 谢谢@Thanks!
ZHAO5210 + 1 我很赞同!
Sir丶九道 + 1 热心回复!
三滑稽甲苯 + 2 + 1 用心讨论,共获提升!
武陵笑笑生1 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
liuqunhey623 + 1 + 1 谢谢@Thanks!
haxcode + 1 + 1 热心回复!
Poko + 1 + 1 谢谢@Thanks!
soseny + 1 + 1 亲测可用
louchen94 + 1 + 1 我很赞同!
威水爷008 + 1 + 1 我很赞同!
lumingfei96 + 1 + 1 用心讨论,共获提升!
Llqqcll + 1 我很赞同!
helh0275 + 1 + 1 感谢分享,确实可用,但是不能打开剩余页,哈哈哈
安道尔的鱼 + 1 + 1 我很赞同!
River213 + 1 + 1 热心回复!
Sionis + 1 + 1 谢谢@Thanks!
nowisfuture + 1 谢谢@Thanks!
马可solo + 1 + 1 因缺思厅
Zayre + 1 谢谢@Thanks!
黄瓜没温度 + 1 + 1 热心回复!
hbzjhg + 1 我很赞同!
山无〇 + 1 + 1 谢谢@Thanks!
Guoxiaowei1028 + 1 谢谢@Thanks!
wknpp + 1 + 1 确实管用!
zyt8212 + 1 + 1 我很赞同!
小朋友呢 + 2 + 1 我很赞同!
Guo.CS + 1 + 1 谢谢@Thanks!
yjn866y + 1 + 1 热心回复!
xiniu233 + 1 + 1 谢谢@Thanks!
yuan01234 + 1 + 1 谢谢@Thanks!
frsm + 1 + 1 谢谢@Thanks!
money4u4us + 1 + 1 谢谢@Thanks!非常牛!
baopushouzhuo + 1 + 1 用心讨论,共获提升!
llp555 + 1 + 1 我很赞同!
Au_L + 1 + 1 用心讨论,共获提升!
絕情 + 1 + 1 我很赞同!
wangyanlin1983 + 1 谢谢@Thanks!
Erebus0qie + 1 + 1 我很赞同!
学学习系 + 1 + 1 我很赞同!
xuemantian0304 + 1 谢谢@Thanks!
Cofei430 + 1 谢谢@Thanks!
wangtiezhu + 1 + 1 谢谢@Thanks!
draeag + 1 + 1 谢谢@Thanks!
森林阳光 + 1 + 1 谢谢@Thanks!
wangfei52 + 1 + 1 热心回复!
Leo625 + 1 + 1 我很赞同!
fengwen18245 + 1 + 1 我很赞同!
teddymvs + 1 谢谢@Thanks!
missmeyou + 1 谢谢@Thanks!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
tfl1 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Coldandcolder + 1 + 1 谢谢@Thanks!
清江堤畔 + 1 我很赞同!
氖气 + 1 + 1 用心讨论,共获提升!
PigBrother + 1 用心讨论,共获提升!
xuanle + 1 + 1 谢谢@Thanks!
SHTsai + 1 + 1 谢谢@Thanks!
y2j + 1 我很赞同!
北方人 + 1 + 1 谢谢@Thanks!
zhczf + 1 我很赞同!
xgs14569 + 1 热心回复!
zyzhang + 1 + 1 热心回复!
lmz444 + 1 + 1 热心回复!
xfwlwork + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
w4112 + 1 + 1 感谢楼主,写了这么多年vue才知道可以这么搞!再出点吧~
13780914665 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

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

fyj159357 发表于 2023-9-6 23:43
谷歌内核的浏览器可以
右键页面检查,
然后点击小齿轮设置,
偏好设置项下面拉到下面,
打勾调试程序下面的“停用JavaScript“,
然后刷新网页。
这时候可以无障碍复制了

免费评分

参与人数 21吾爱币 +21 热心值 +16 收起 理由
wavincao + 1 + 1 我很赞同!
童话镇大灰狼 + 1 + 1 我很赞同!
wqpojie + 1 + 1 我很赞同!
nanckskier + 1 + 1 热心回复!
文山 + 1 + 1 我很赞同!
RichYYN + 1 我很赞同!
恶魔天尊 + 1 + 1 我很赞同!
resu + 1 热心回复!
爽爽哒 + 1 + 1 我很赞同!
root12138 + 1 + 1 谢谢@Thanks!学到了
fengbolee + 1 + 1 热心回复!
yql0212 + 1 + 1 我很赞同!
Fgh745799516 + 1 我很赞同!
lqjxcf + 1 + 1 用过,非常方便
ttyylfd + 1 + 1 我很赞同!
Cofei430 + 1 谢谢@Thanks!
dzy75 + 1 + 1 热心回复!
evill + 1 + 1 我很赞同!
pzrmw + 1 我很赞同!
Leen + 1 + 1 谢谢@Thanks!
jy00812995 + 1 + 1 谢谢@Thanks!

查看全部评分

 楼主| 李恒道 发表于 2023-9-6 06:58
dx163 发表于 2023-9-6 06:37
小白不知道怎么用

直接在控制台输入document.querySelector('.header-wrapper').__vue__.$store.state.vipInfo.isVip=true就可以了

免费评分

参与人数 5吾爱币 +6 热心值 +5 收起 理由
liyitong + 1 + 1 好家伙,冒充VIP用户
daymissed + 1 + 1 我很赞同!
wangguang + 2 + 1 佬,亲测可用
yanguichao + 1 + 1 亲测可用。
zuohaoda + 1 + 1 我很赞同!

查看全部评分

xiaooooooo 发表于 2023-9-6 08:57
哥哥牛逼!羡慕拉斯维加斯 看见配型的第一反应是小心腰子!
sndncel 发表于 2023-9-6 08:46
本帖最后由 sndncel 于 2023-9-6 08:48 编辑

测试了一下,页面显示已复制,但是你粘贴过去的时候,还是没有任何东西。。。。。
QQ截图20230906084756.png

免费评分

参与人数 1热心值 +1 收起 理由
zleizero + 1 我很赞同!

查看全部评分

rhinorhino 发表于 2023-9-6 07:26
试了一下,还是不能复制,控制台提示:GET https://wkctj.baidu.com/click.gif?logType=normal&behavior=click&className=&inlineLogData=&sessionId=1466030359-1466030359--&channel=OTHER&phSize=9&linkSize=2&preUrlType=OTHER&page=view&bizType=ndPcView&v2022=1&ssr=1&docId=5d102fd05322aaea998fcc22bcd126fff7055dfd&docTitle=%E7%AB%AF%E5%8D%88%E8%8A%82%E6%97%A5%E8%AE%B0(15%E7%AF%87)&isLogin=1&isVip=0&leftdays=0&isNewUser=1&isSuperVip=0&renewStatus=0&tplName=editor&fileTypeKey=1&docBizCategory=3&highQuerySize=0&isPaied=0&isRepeatDown=0&isCreater=0&wkTestId=100496,80139,80163,100411,80438&pageCount=7&showPage=1&region=0&referType=NOT_BAIDU&riskScore=0&isFromBdIME=0&sampleId=109673_1,109650_1,109869_1,111936_3,108997_1,110591_2,107150_3,108168_2,108342_1,108440_2,108800_2,109093_2,109547_2,109484_1,109587_1,109771_3,109464_1,110227_2,110242_2,110812_2,112002_2,112144_2,111985_2,112714_2,112123_2,107244_3,107315_2,105640_2,111857_2,112450_2,112550_2,112923_1&trackPath=&flowType=1&flowrate=1&rawIntrPage=1&interceptPage=1&policyId=vIWopsMn0pRXzfcBEYEOiw==&backendIsIntercept=2&vst1st=1&pid=1&bid=1&fr=4&act_id=103278&url=https%3A%2F%2Fwenku.baidu.com%2Fview%2F5d102fd05322aaea998fcc22bcd126fff7055dfd.html%3Ffr%3Dhp_Database%26_wkts_%3D1693956272164&refer=https%3A%2F%2Fwww.52pojie.cn%2F&t=1693956301881&ie=utf-8 net::ERR_BLOCKED_BY_CLIENT
13729181580 发表于 2023-9-6 05:26
感谢分享!
netxboy 发表于 2023-9-6 11:11
wyao 发表于 2023-9-6 09:35
F12  然后勾选这个就搞定了。

没有用。
打开页面再停用不起作用,如停用了再刷新,连页面都加载不出来。
platocn001 发表于 2023-9-6 06:06
感谢分享
晓渡寒沙 发表于 2023-9-6 06:18
不明觉厉
bulesoft 发表于 2023-9-6 06:33
手机为啥能直接复制黏贴能呢
 楼主| 李恒道 发表于 2023-9-6 06:36
bulesoft 发表于 2023-9-6 06:33
手机为啥能直接复制黏贴能呢

手机有降级
桌面端为了视觉效果采用了Canvas
手机端依然是传统的Dom渲染模式
所以可以复制粘贴
asd124689 发表于 2023-9-6 06:53
是需要JavaScript 知识吗
 楼主| 李恒道 发表于 2023-9-6 06:58
asd124689 发表于 2023-9-6 06:53
是需要JavaScript 知识吗

是的,需要一点js知识,主要其实还是对vue的分析
mqw921 发表于 2023-9-6 07:11
李恒道 发表于 2023-9-6 06:58
直接在控制台输入document.querySelector('.header-wrapper').__vue__.$store.state.vipInfo.isVip=true ...

小白一枚,控制台是F12吗?往哪里输入?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-14 14:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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