南强小屋 Design By 杰米
题目网址:https://match.yuanrenxue.com/match/2
写的比较新手向,大佬可能会觉得看着比较墨迹,如果有错误的地方欢迎指出。
全文手把手扣代码补环境,几乎包含了绝大部分可能会踩的坑。
土豪通道:
猿人学第2题手把手补环境2.7z2022-5-26 10:10 上传点击文件名下载附件
不过建议还是自己动手扣一下,下面是正文

猿人学第2题手把手补环境
这道题的题目要求是获取前五页的热度值并求得累加和,首先抓包看一下数据请求方式
猿人学第2题手把手补环境
可以看到请求数据的就只有一个get请求,本题的题目就是动态cookie,从实际请求中也可以看出m就是那个加密的参数,所以完成这道题的关键就是如何获取m。
猿人学第2题手把手补环境
清除缓存重新加载界面遇到了无限debugger,直接鼠标右键停用断点过掉。刷新页面
猿人学第2题手把手补环境
猿人学第2题手把手补环境
可以看到两个一样的请求,但是一个没有cookie,看不到响应,且响应头没有setcookie,另一个带有cookie m 并且正好是网页的几面内容。由此可以看出,cookie m的值是第一次请求后由js生成出来的。
使用postman尝试发送第一个get请求
猿人学第2题手把手补环境
可以看到是将js代码以script标签的形势放入了html文档中,进一步验证了cookie是由js生成的猜想。知道了大概位置,就可以开始找具体代码了。
猿人学第2题手把手补环境
在源代码选项卡中找到事件监听断点, 勾选脚本,这样在遇到js时会自动断下,清除浏览器中保存的cookie,刷新界面
猿人学第2题手把手补环境
成功将页面断下,不过可以看到此处的代码与postman收到的不一样,点击继续运行
猿人学第2题手把手补环境
成功来到postman验证的代码,格式化以后尝试寻找cookie生成位置, 发现代码混淆严重,只能动态调试。
现在在控制台输入hook cookie的代码(这里我是在控制台手工hook,有条件的话也可以用油猴脚本等浏览器插件或者fiddler插件之类的进行hook),
猿人学第2题手把手补环境
(function () {    Object.defineProperty(document, 'cookie', {        set: function (val) {            debugger;            return val;        },    });})();
hook好以后 让网页继续运行,成功断在cookie生成位置
猿人学第2题手把手补环境
此时的m已经生成出来了,不过可以通过调用堆栈找到生成的位置。
猿人学第2题手把手补环境
将代码格式化以后可以看到,cookie的生成位置在4922行这一超长的代码中
[Asm] 纯文本查看 复制代码
document[$dbsm_0x42c3(qqLQOq, iOiqII) + $dbsm_0x42c3(q1IoqQ, QQlLlq)] = _0x5500bb['\x4e\x74\x44' + '\x72\x43'](_0x5500bb[$dbsm_0x42c3(qqqQoq, oqQiiO) + '\x6d\x65'](_0x5500bb[$dbsm_0x42c3(Ioo0ql, olq0Oq) + '\x6d\x65'](_0x5500bb[$dbsm_0x42c3(qOIqQi, OOqIQi) + '\x72\x44'](_0x5500bb[$dbsm_0x42c3(Q1qoqQ, lILOOq) + '\x72\x44'](_0x5500bb[$dbsm_0x42c3(qOO1Q0, oiqlQQ) + '\x72\x44'](Ql1OO0, _0x5500bb['\x7a\x76\x67' + '\x6c\x77'](_0x3c9ca8)), Qoqq0I), _0x5500bb[$dbsm_0x42c3(iqOiQ0, QOiq0Q) + '\x47\x6b'](_0x313b78, _0x160e3a)), lOo0QQ), _0x160e3a), _0x5500bb[$dbsm_0x42c3(qiOOiO, liQIoQ) + '\x4e\x5a']),

猿人学第2题手把手补环境
将等号右边的一大长串代码放到控制台中查看,可以确定一大长串代码就是m的生成位置 。
仔细看看这一大对代码的结构,可以看出虽然很长,但是也是由一部分一部分拼接出来的。
将代码拆解一下得到如下结果
[JavaScript] 纯文本查看 复制代码
_0x5500bb['\x4e\x74\x44' + '\x72\x43'](_0x5500bb[$dbsm_0x42c3(qqqQoq, oqQiiO) + '\x6d\x65'](_0x5500bb[$dbsm_0x42c3(Ioo0ql, olq0Oq) + '\x6d\x65'](_0x5500bb[$dbsm_0x42c3(qOIqQi, OOqIQi) + '\x72\x44'](_0x5500bb[$dbsm_0x42c3(Q1qoqQ, lILOOq) + '\x72\x44'](_0x5500bb[$dbsm_0x42c3(qOO1Q0, oiqlQQ) + '\x72\x44'](Ql1OO0, _0x5500bb['\x7a\x76\x67' + '\x6c\x77'](_0x3c9ca8)), Qoqq0I), _0x5500bb[$dbsm_0x42c3(iqOiQ0, QOiq0Q) + '\x47\x6b'] (_0x313b78, _0x160e3a)), lOo0QQ), _0x160e3a), _0x5500bb[$dbsm_0x42c3(qiOOiO, liQIoQ) + '\x4e\x5a'])

可以看到,出现最多的东西,就是_0x5500bb
猿人学第2题手把手补环境
通过控制台验证可以看到,这个_0x5500bb里面包含了很多字符串和函数,也就是说上面的代码都是在调用它里面的函数。
那么只需要验证里面的东西都是什么,就可以找到m的生成位置了。
猿人学第2题手把手补环境
利用控制台将内容简单还原方便后续观察,得到如下结果
[JavaScript] 纯文本查看 复制代码
_0x5500bb['NtDrC'](_0x5500bb['KGBme']=(_0x5500bb['KGBme'](_0x5500bb['mQKrD'](_0x5500bb['mQKrD'](_0x5500bb['mQKrD'](Ql1OO0, _0x5500bb['zvglw'](_0x3c9ca8)), Qoqq0I), _0x5500bb['wWbGk'] (_0x313b78, _0x160e3a)), lOo0QQ), _0x160e3a), _0x5500bb['TfZNZ'])

可以看出,这是一个函数套函数的大套娃,接下来进行逐一验证
猿人学第2题手把手补环境
可以看出,最后一个调用的函数结果是cookie中最后的部分,而_0x160e3a则是一个时间戳(_0x313b78, _0x160e3a)的结果仍然是一个时间戳,而_0x5500bb['wWbGk'](_0x313b78, _0x160e3a)的值就是cookie的前半部分。还记得之前找到的cookie是什么样的嘛?
猿人学第2题手把手补环境
综上所述,我们可以得出
[JavaScript] 纯文本查看 复制代码
Cookie = _0x5500bb['wWbGk'](_0x313b78,_0x160e3a)+lOo0QQ+_0x160e3a

再通过控制台看一下这个wWbGk是个什么东西
猿人学第2题手把手补环境
原来是一个函数,里面有两个参数,就是用第一个参数调用第二个参数 。进一步简化上面的等式
[JavaScript] 纯文本查看 复制代码
Cookie = _0x313b78(_0x160e3a)+"|"+_0x160e3a// _0x160e3a为时间戳//此时值为: 1653183600000

找到了生成逻辑以后,就可以开始补环境大法了。
我这里使用装了NodeJs插件的Pycharm进行调试,当然,都是根据个人喜好自由选择。
猿人学第2题手把手补环境
这里提示了_0x313b78没有找到,我们去控制台看看它是怎么定义的
猿人学第2题手把手补环境
可以看到这是一个函数,在源代码中搜索找到它的位置,将其完完整整的抠出来,再次调试js。
猿人学第2题手把手补环境
又提示_0x5500bb没有定义,接下来只需要不停的重复上面的步骤,什么没有定义,就去源代码里面找到它并将其扣下来。
这里还有一个需要注意的小技巧,就是你将扣下来的代码放到自己的js文件中时,要注意它提示not defined的行是哪一行,找到它然后放在那一行所在的函数的前面即可。一味的放到文件开头有时候可能也会出错。
猿人学第2题手把手补环境
这里可以看到_0x5500bb是一个大列表,而它的实质则是上面的_0x443ddb,所以这里要赋值的这一行,到上面的整个_0x443ddb都给扣下来。
猿人学第2题手把手补环境
补完以后又开始提示未定义了,通过控制台确定是什么东西以后继续补。
猿人学第2题手把手补环境
这里碰到个乱码没有定义,去控制台看是什么发现报错了。但是不要慌,在源码里面先搜一下看看
猿人学第2题手把手补环境
可以看到这个东西是在一个自执行函数里面定义的,为了防止多余的变量污染,秉持着缺啥补啥的原则,这里我只把这一大串乱码扣下来补了上去,而不是整个函数都扣。在扣的时候还发现这串定义的乱码正好接在了前面补的代码头上,抠出来的代码也随着原来的样子拼了上去。(这个和前面提到的将抠出来的代码放到报错行前面并不冲突)
再次运行调试
猿人学第2题手把手补环境
出现了新的未定义,继续开始扣扣补补。
猿人学第2题手把手补环境
在补完一个大数组以后,猛的发现NodeJs报错了,运行不了?遇到这个问题的时候,把整个代码拿出来放到真实的浏览器去debug一下先。
猿人学第2题手把手补环境
新开一个 标签页打开开发人员工具,避免前面补环境用的标签页出现意外。
在源代码选项卡中找到代码段(找不到的话可以点那个向右的然后再进代码段),新建一个代码段将刚才抠出来的所有代码复制进去。
为了方便调试,咱们在所有代码的最前面,也就是第一行加上一个debugger,来手动执行代码。
猿人学第2题手把手补环境
在代码段上右键运行代码,成功进入debug状态,然后点击按钮一个函数一个函数的来执行。
猿人学第2题手把手补环境
还没点几下,在执行到乱码这里时突然整个标签页都卡死了,开发者工具也无法操作,基本上可以确定问题就是出现在这里了。
猿人学第2题手把手补环境
刷新刚才新建的标签页重新来到开发者工具。将第一行的debugger删除掉在乱码前面重新加上。 重新运行代码段,在进入debug状态后,点击进入函数调用进一步查看出错的地方。
猿人学第2题手把手补环境
点着点着你就会发现当执行到这里的时候,进入了死循环,怎么也出不去。这里就是NodeJs执行报错的原因了。
猿人学第2题手把手补环境
向上翻看一下源码可以看到,只要来到了这个函数就会必然进入这个死循环,所以我们必须想办法将其绕过。
从代码和和调用堆栈中都可以看出,在WjJIeN函数中有一个if语句,如果!Boolean(~_0x4859ef)为真的话就会返回一个_0x4859ef为假的话则会调用这个死循环函数。
所以我们需要让这个布尔值变成是真,但是这个布尔值是通过判断参数来决定的。通过调用关系可以看出这个参数是由上一个函数提供的。
分析到这里就已经很明显了,是否进入这个死循环就是由vnuqco函数中的_0x3fba94决定的。而它则是由下面这个三元表达式决定的
[JavaScript] 纯文本查看 复制代码
_0x2940ac['test'](this['XxpyjG']['toString']()) ? --this['yHmSUE'][0x1] : --this['yHmSUE'][0x0];

使用控制台验证判断的表达式
猿人学第2题手把手补环境
可以看到,是调用_0x2940ac的test方法。如果你仔细看前面的代码,就会发现这个_0x2940ac其实是定义的一个正则表达式,而被检测的内容,也恰好就是上面的函数定义。
猿人学第2题手把手补环境
正则表达式的内容如下:
[Asm] 纯文本查看 复制代码
/\w+ *\(\) *{\w+ *['|"].+['|"];? *}/

就是用这个正则表达式去匹配上面定义的XxpyjG的函数代码。匹配成功则返回true否则返回false。
其实如果毕竟懂正则表达式的话,应该可以看出这个表达式就是验证代码是否被格式化过。我这里在控制台验证一下
猿人学第2题手把手补环境
调试的时候默认情况下是false的,但是把格式化代码生成的空格和换行符删掉后再次匹配就变成了true。
修改好函数定义以后,清除掉所有的debugger和断点。重新尝试运行脚本,一定要主要这里的函数定义必须把所有的换行和多余的空格(return后面那一个不算)全部清理干净,可以参考我的图片。
猿人学第2题手把手补环境
系统提示有东西未定义,而不是直接卡死,说明刚才那个格式化检测已经过掉了。
此时将Pycharm中的js文件对应修改好后,进行调试
猿人学第2题手把手补环境
也是提示未定义,没有问题。继续重复之前的步骤,准备扣代码补环境。
但是此时你再仔细观察一下,会发现报错的这行代码的上面不是有一个已经定义的_0x313b78吗?怎么会提示还提示没有定义呢。其实在这里是因为前面补的一大长串代码的最后面是一个逗号,我们将其改成语句结束的分号再调试一下。
猿人学第2题手把手补环境
成功通过,但是又报了一个新的无定义。但是这个报错的内容怎么好像找不到?其实是因为上面的字符串被转码后导致的,你可以根据报错的行号和错误提示上面的原代码来找到具体的内容。
找到以后在控制台查看这是个什么东西
猿人学第2题手把手补环境
可以看到这是调用的_0x5500bb里面的KNqZI函数。
利用之前过格式化检测的方法,将代码放到浏览器中进行调试
猿人学第2题手把手补环境
可以看到函数显示未定义,而且里面调用的函数也和原版中的不一样。
猿人学第2题手把手补环境
通过比较可以看出,所有的参数都是没问题一致的,所以问题只能出在$dbsm_0x42c3上面
猿人学第2题手把手补环境
这里可以看到这个函数虽然是已经补过的,但是上面的自执行函数的参数却是这个函数。
其实这里是一个比较常见的混淆套路,一个大数组保存16进制的函数名,然后有一个在代码里出现频率极高的解密函数(此处就是$dbsm_0x42c3),除了解密函数以外,还有一个用于将16进制字符串还原的移位函数(也就是上面那个参数是解密函数的自执行函数)。
在上次补解密函数的时候,没有补上这个移位函数,所以解密函数解密出来的内容出了错(乱码),自然也就找不到正确的函数,也就会报函数未定义了。
解决办法很简单,只要把移位函数补上去即可。
猿人学第2题手把手补环境
成功通过,然后继续开始扣代码补环境。
在补移位函数的时候需要注意下里面还存在格式化检测,有兴趣了解具体原因的可以参考上次过格式化检测的方法来搞定。如果懒得调试可以直接将移位函数压缩,然后再补上即可。
补完移位函数后会有非常多的函数要一个一个补,一定要有耐心,自行参考前面补环境的方法,此处不再详解。
当补到_0x1316f4的时候你可能会发现调试js文件时,node会一直执行,其实这里是因为你扣代码的时候把最后的自执行括号给加上去了,实质上这里应该是一个函数
猿人学第2题手把手补环境
在补环境的时候要注意与原版的要保持一致,不清楚时可在debugger的控制台中查看。
补环境的途中你可能会碰到如下报错:
猿人学第2题手把手补环境
提示这个是因为要用到浏览器的属性,而我们用NodeJs没有这个环境导致的,只需要在文件开头补上即可,环境代码如下:
[JavaScript] 纯文本查看 复制代码
window = global;window.navigator = {};

补到最后,你会发现,程序直接运行结束了
猿人学第2题手把手补环境编辑
这说明环境已经补的差不多了。在底下console.log一下看看
猿人学第2题手把手补环境
又报了一个未定义,但是这个报错的确实console.log,看来是上面的环境代码为了防止调试把console.log给改掉了。我们在文件的最开头把console.log保存一下然后再调用咱们自己保存的来调试。
猿人学第2题手把手补环境成功打印出m的值。
至此,整个补环境已经完成,接下来只需要调用这个js就可以获取到m的值
标签:
猿人学第2题手把手补环境

南强小屋 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
南强小屋 Design By 杰米

评论“猿人学第2题手把手补环境”

暂无猿人学第2题手把手补环境的评论...

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?