猿人学爬虫题目第一题: 《抓取所有机票价格》,该案例非常适合js新手入门。

题目链接:http://match.yuanrenxue.com/match/1


F12打开控制台,可见debugger出现,右键选择Never pause here;

接下来F5,就可以跳过debugger了,查看数据包。

看一下请求参数:

直接点击查看Initiator进行调试。

随便选一个进来断点,选择下一页触发debug

没找到就点右侧的call stack,按顺序点一下看


点到request看到了有一端不能格式化的代码,最好是把这个代码全部复制到html文件中,然后自己处理下。

从这里可以看出:
timestamp = 13位时间戳 + 100000000;

把没用的删除掉,开始自己拼oo0O0()方法。
其中window.a:

然后缺什么补什么,在控制台去找更方便一些。


执行时如果报错:

  • ReferenceError: atob is not defined

atob方法:natice code , 用于解码使用 base-64 编码的字符串。
如果有node环境的话,可以安装一下 npm install atob
(其实也可以换一种方法处理,比如返回数据后使用python来进行base64转换)

const atob = require('atob');
// npm install atobfunction oo0O0(mw) {window = {};document = {};window.b = '';window.a = ' 太长了,这里不贴进来了'document.e = 'fromC';document.g = 'harCode';document.f = 'charCo';document.h = 'deAt';window.c = 5;for (var i = 0, len = window.a.length; i < len; i++) {window.b += String[document.e + document.g](window.a[i][document.f + document.h]() - i - window.c)}var U = ['W5r5W6VdIHZcT8kU', 'WQ8CWRaxWQirAW=='];var J = function (o, E) {o = o - 0x0;var N = U[o];if (J['bSSGte'] === undefined) {var Y = function (w) {var m = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=',T = String(w)['replace'](/=+$/, '');var A = '';for (var C = 0x0, b, W, l = 0x0; W = T['charAt'](l++); ~W && (b = C % 0x4 ? b * 0x40 + W : W, C++ % 0x4) ? A += String['fromCharCode'](0xff & b >> (-0x2 * C & 0x6)) : 0x0) {W = m['indexOf'](W)}return A};var t = function (w, m) {var T = [], A = 0x0, C, b = '', W = '';w = Y(w);for (var R = 0x0, v = w['length']; R < v; R++) {W += '%' + ('00' + w['charCodeAt'](R)['toString'](0x10))['slice'](-0x2)}w = decodeURIComponent(W);var l;for (l = 0x0; l < 0x100; l++) {T[l] = l}for (l = 0x0; l < 0x100; l++) {A = (A + T[l] + m['charCodeAt'](l % m['length'])) % 0x100, C = T[l], T[l] = T[A], T[A] = C}l = 0x0, A = 0x0;for (var L = 0x0; L < w['length']; L++) {l = (l + 0x1) % 0x100, A = (A + T[l]) % 0x100, C = T[l], T[l] = T[A], T[A] = C, b += String['fromCharCode'](w['charCodeAt'](L) ^ T[(T[l] + T[A]) % 0x100])}return b};J['luAabU'] = t, J['qlVPZg'] = {}, J['bSSGte'] = !![]}var H = J['qlVPZg'][o];return H === undefined ? (J['TUDBIJ'] === undefined && (J['TUDBIJ'] = !![]), N = J['luAabU'](N, E), J['qlVPZg'][o] = N) : N = H, N};console.log(eval(atob(window['b'])[J('0x0', ']dQW')](J('0x1', 'GTu!'), '\x27' + mw + '\x27')));return ''
}
console.log(oo0O0(1611212930238))

到这里并没有结束,返回最开始,可以看到 m 其实是加密之后再加上window.f,
然后以字符串形式和 timestamp/1000进行拼接,得到最终的参数m。

打印了一下windows.f 发现不是固定参数,

全局中也没有搜索出来

这样说明,windows.f 可能是更改了字符或者编码或者用了什么代替

试了好几个地方,才找到window.f

这里打印了下 base64转码后的代码,发现是一段js,格式化之后删除无用的内容。


所以在看这个图,整体的生成流程已经掌握了。
另外我修改后生成了两遍md5的值,后来发现 oo0O0()并没有返回值 = =,是我自己加上了。
并且oo0O0()和window.f相同。

测试: 把 node 生成的m拿出来,直接使用python requests 请求,成功返回数据。


完整js代码:

const atob = require('atob');
// npm install atobfunction oo0O0(mw) {window = {};document = {};window.b = '';window.a = "!!!!!!!!!A太长了,此处省略了!!!!!!!!!!!!!!!!!"document.e = 'fromC';document.g = 'harCode';document.f = 'charCo';document.h = 'deAt';window.c = 5;for (var i = 0, len = window.a.length; i < len; i++) {window.b += String[document.e + document.g](window.a[i][document.f + document.h]() - i - window.c)}var U = ['W5r5W6VdIHZcT8kU', 'WQ8CWRaxWQirAW=='];var J = function (o, E) {o = o - 0x0;var N = U[o];if (J['bSSGte'] === undefined) {var Y = function (w) {var m = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=',T = String(w)['replace'](/=+$/, '');var A = '';for (var C = 0x0, b, W, l = 0x0; W = T['charAt'](l++); ~W && (b = C % 0x4 ? b * 0x40 + W : W, C++ % 0x4) ? A += String['fromCharCode'](0xff & b >> (-0x2 * C & 0x6)) : 0x0) {W = m['indexOf'](W)}return A};var t = function (w, m) {var T = [], A = 0x0, C, b = '', W = '';w = Y(w);for (var R = 0x0, v = w['length']; R < v; R++) {W += '%' + ('00' + w['charCodeAt'](R)['toString'](0x10))['slice'](-0x2)}w = decodeURIComponent(W);var l;for (l = 0x0; l < 0x100; l++) {T[l] = l}for (l = 0x0; l < 0x100; l++) {A = (A + T[l] + m['charCodeAt'](l % m['length'])) % 0x100, C = T[l], T[l] = T[A], T[A] = C}l = 0x0, A = 0x0;for (var L = 0x0; L < w['length']; L++) {l = (l + 0x1) % 0x100, A = (A + T[l]) % 0x100, C = T[l], T[l] = T[A], T[A] = C, b += String['fromCharCode'](w['charCodeAt'](L) ^ T[(T[l] + T[A]) % 0x100])}return b};J['luAabU'] = t, J['qlVPZg'] = {}, J['bSSGte'] = !![]}var H = J['qlVPZg'][o];return H === undefined ? (J['TUDBIJ'] === undefined && (J['TUDBIJ'] = !![]), N = J['luAabU'](N, E), J['qlVPZg'][o] = N) : N = H, N};result = eval(atob(window['b'])[J('0x0', ']dQW')](J('0x1', 'GTu!'), '\x27' + mw + '\x27'));return result;}function getM() {var timestamp = Date.parse(new Date()) + 100000000;var m = oo0O0(timestamp.toString());var result = m + '丨' + timestamp / 1000;console.log(result);return result
};

调用 getM()方法即可返回m即可。

Js逆向-猿人学(1)源码混淆相关推荐

  1. Js逆向 | 猿人学爬虫攻防大赛 | 第一题: js 混淆 - 源码乱码(多图预警!!手把手教学!!)

    地址: 第一题地址 题目: 抓取所有(5页)机票的价格,并计算所有机票价格的平均值,填入答案. 初探: 进入网站,惯例先开F12康康 这里被 debugger 卡住了: 你可以 选中行号点右键点 Ed ...

  2. 《封号码罗》关于js逆向猿人学第一题m值的获取[纯补环境](二十四)

    网上有很多资料,包括视频都讲解了m值的生成方式,但是我自己总是看过之后,有很多疑惑,所以我自己再总结一遍. 抓包看看请求 m值得生成位置 用AST简单解混淆一下,源码就是整个混淆的js复制到本地文件 ...

  3. JS逆向:猿人学爬虫比赛第九题详细题解

    实战地址 http://match.yuanrenxue.com/match/9 抓包分析 地址栏输入 地址,按下F12并回车,浏览器停在这里: 不用理会它,点击下图所示的按钮: 按下F8,让浏览器继 ...

  4. JS逆向:猿人学爬虫比赛第五题详细题解(下)

    上篇文章,我们已经找到了加密的地方,关键代码是这样的: _$Ww = _$Tk["enc"]["Utf8"]["parse"](window ...

  5. axis2 webservice入门学识(JS,Java,PHP调用实例源码)

    来源:http://www.myexception.cn/web/952419.html axis2 webservice入门知识(JS,Java,PHP调用实例源码) 背景简介 最近接触到一个银行接 ...

  6. HTML网页设计期末课程大作业 ~中国茶文化5页面带轮播(HTML+CSS+JS)~ 学生网页设计作业源码

    HTML网页设计期末课程大作业 ~ 中国茶文化5页面带轮播(HTML+CSS+JS)~ 学生网页设计作业源码 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大?HTML网页作业无从 ...

  7. 编译与代码安全之认识(二):Source2Source源码混淆方法

    一.说明:            针对源码混淆其实在代码保护中应用很多,大部分是应用在像JS这种脚本语言中,因为很多时候JS是以源码的形式出现,网上有很多关于JS保护的工具,比较出名的是JSugly和 ...

  8. HTML期末作业课程设计期末大作业——体育排球5页面带注册HTML+CSS+JS(学生网页设计作业源码)

    HTML期末作业课程设计期末大作业--体育排球5页面带注册HTML+CSS+JS(学生网页设计作业源码) 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大?HTML网页作业无从下手 ...

  9. JAVA毕业设计vue.js开发红酒网站计算机源码+lw文档+系统+调试部署+数据库

    JAVA毕业设计vue.js开发红酒网站计算机源码+lw文档+系统+调试部署+数据库 JAVA毕业设计vue.js开发红酒网站计算机源码+lw文档+系统+调试部署+数据库 本源码技术栈: 项目架构:B ...

最新文章

  1. 吊打 Tomcat ,Undertow 性能很炸!!
  2. 进程、线程和协程的区别和联系(TX)
  3. SAP Analytics Cloud的Sample Story
  4. Swift快速参考手册
  5. 深度学习笔记(29) 1×1 卷积
  6. Ajax提交数据判断员工编号是否存在,及自动填充与员工编号所对应的员工姓名。...
  7. python webdriver 登录163邮箱发邮件加附件, 外加数据和程序分离,配置文件的方式...
  8. 读书笔记_Effective C++_条款一:将C++视为一个语言联邦
  9. docker--删除container和image
  10. 《Windows游戏编程大师技巧》一、学海无涯
  11. Linux内核编程11期:设备树(device tree)
  12. winpe硬盘安装linux,winpe+linux安装到移动硬盘
  13. linux查找文件夹命令
  14. Unity背包系统(二)背包UI设计
  15. android国外壁纸app,听说在国外很火?Action安卓启动器体验
  16. 六度拓扑(www.6dtop.com)正式开源啦~~~(V1.0)
  17. 通过OpenWrt路由器实现王者荣耀、快手、抖音过滤
  18. c语言实验教学软件,C语言实验教学法综述
  19. halcon学习和实践(第一个范例threshold.hdev)
  20. gitee基本使用方法(Tortoisegit)

热门文章

  1. 在Ubuntu9.10上折腾Maemo SDK5的过程
  2. 转贴||《送别》 长亭外,古道边,芳草碧连天。||王国维之死,是一个世纪的谜语...
  3. 苹果知名开发者怒“怼”:GitHub 不可信,俄罗斯开发者贡献的项目遭毁灭性打击!...
  4. 记录一次服务器被攻击的事件,被当作了肉鸡
  5. FCOS论文复现:通用物体检测算法
  6. 亚马逊条码标签(SSCC/FBA)的制作打印
  7. Python爬虫之requests+正则表达式抓取猫眼电影top100以及瓜子二手网二手车信息(四)...
  8. 一棵树是否为另一棵树的子结构
  9. 用友U8CO接口开发方式之映射(二)
  10. 把insert和update写成一个复合语句