1.介绍:

  要分析的网站是:https://www.qimai.cn/rank
  ①当你打开网站,打开控制台的时候,网站有debugger检测,会陷入一个死循环,让你无法调试,如下图:
  ②在解决掉debugger问题后(稍后介绍如何解决),点击到你想爬取的数据页面如:https://www.qimai.cn/rank/index/brand/paid/device/iphone/country/cn/genre/36/date/2018-11-11 查看ajax请求,你会看到你想要的数据,but每个重要请求都会有个analysis字段,此字段便是本文的重点分析对象。如下图:
下面正式介绍如何解决检测deugger及其analysis的逆向分析

2.准备工具:

  抓包工具:fiddler、charles
  浏览器:firefox、chrome
  工具凭个人喜好选择

3.解决debugger检测:

  ①回到本文第一张图片,查看黄色框部分。查看堆栈,点击anonymous下的e,跳转到了app.xxxxxxx.js文件的debugger执行函数位置了,如下图:

②分析下var a = [ 'r','e', 'g','g', 'u', 'b','e', 'd'].reverse().join(''); 这个变量a不就是“debugger”嘛,往下继续自动执行递归函数e调用debugger,造成了无法让我们正常调试。
③ok!我们已经知道是哪个函数在搞的鬼了,也知道这个函数在哪个文件了。下边我们改如何注释掉这段函数呢?我的解决办法是抓包!关于抓包工具如何使用这里就不介绍了,不会的同学请自行百度“抓包https”
打开抓包工具,拦截app.xxxxxx.js文件注释掉以下代码块
!function e(n) { (1 !== ('' + n / n).length || 0 === n) && function () { }.constructor(a) (), e(++n) }(0)
如下图:
已经可以正常调试了

4.analysis逆向分析:

经过以上步骤已经可以正常调试了,下边我们讲下我的分析思路。
①定位analysis字段的生成位置(这一步有很多方法)
  我的第一反应是全项目搜索,command+shift+f(mac版本firefox控制台快捷键) 搜索“analysis”,然而并没有搜到想要的结果。
  尝试第二种办法,添加xhr断点,关键词api,即api.qimai.cn中的api,刷新网页。如下图:
分析下代码h为XMLHttpRequest对象,便是发出请求的最后一步,然后看下图右侧红框堆栈部分,如下图:
自上而下点击堆栈开始做断点吧,看看哪部分代码块有自己想要的线索。
花费好长时间,最终在get堆栈定位到app.xxxxx.js文件的以下位置,找到了“analysis",继续断点得出r便是analysis的值。r由两个函数l.d和l.h处理o后得出

②解决变量o
分析下代码:这个变量o初始值不就是url的参数值然后做了个排序,然后拼成的字符串嘛,如上图url:
www.qimai.cn/rank/marketRank/market/3/category/-2/country/cn/collection/topselling_free/date/2018-11-13----->[3,-2,cn,topselling_free,2018-11-13],
然后做了个排序拼接在一起就是-22018-11-113cntopselling_free,这里经过一个l.d函数,让我们看下这个函数做了什么事,选中l.d进去h(a)函数:

        function h(a) {return x()(encodeURIComponent(a).replace(/%([0-9A-F]{2})/g, function(a, e) {return r("0x" + e)}))}

又出来个x(),继续步进,到了下图位置,下图命名为图1

t就是上述的o,也就是url参数;
console下e.from(t.toString(),“binary”)获得了一个数组, 赋值给了n
n.toSting(‘base64’)即是加密后的o

下面我们看看七脉是如何给o进行加密的
首先我们先看看是如何获得的数组,先进入e.from函数,又到s函数,参数依然是url的参数,这网站弄的真够绕的,下图命名为图2
继续进入s函数,传参url参数,下图命名为图3:

分析下上图中f函数参数,重点来了!!!!!!!
t=null,
e=url参数
n=“binary”,
函数o(t,r)生成了一个长度和url参数等长度且全部为0的数组,并赋值给t
继续进入t.write(e,n)
下图命名为图4

继续write函数调用k函数,进入k函数传参t=url参数,e=“binary”, n =undefined!
下图命名为图5

k调C,C调K(W(e)),console下W(e)得到了数组,这个数组就是图1中出现的数组!!!!继续步进进入W看看url参数怎么转成数组的,下图命名为图6

            function W(t) {for (var e = [], n = 0; n < t.length; ++n)e.push(255 & t.charCodeAt(n));return e}

遍历t,获取每个下标元素对应的 ASCII 数值,然后和255进行&运算。charCodeAt 和python中ord函数作用相同
ok!步出!步进看K函数如何将W得到的数组进行加密的
下图命名为图7

K函数并没有对此数组进行操作,return i; i的数值和e相同!!
至此我们得到了图1中的数组,将数组进行一个toString(‘base64’)操作即是加密结果

如果至此你已经蒙圈了,可以将断点打到图一中的n.toString(‘base64’),为了防止其他断点的干预,我习惯将其他断点先关闭,然后刷新,重新看数组如何变成base64的。
如果你还很清楚,那直接步出步出步出。。。,到图1所示代码块,如下状态

继续步进

进入到M
console下Q.fromByteArray(t),即是加密后的o,进入到fromByteArray

以下函数是对数组加密,即生成base64字符串的过程,直接调用u即可

//对数组进行加密function u(t) {  //用到了sfor (var e, n = t.length, r = n % 3, i = "", o = [], a = 16383, u = 0, c = n - r; u < c; u += a)o.push(s(t, u, u + a > c ? c : u + a));return 1 === r ? (e = t[n - 1],i += l[e >> 2],i += l[e << 4 & 63],i += "==") : 2 === r && (e = (t[n - 2] << 8) + t[n - 1],i += l[e >> 10],i += l[e >> 4 & 63],i += l[e << 2 & 63],i += "="),o.push(i),o.join("")}function s(t, e, n) { //用到了afor (var r, i = [], o = e; o < n; o += 3) r = (t[o] << 16 & 16711680) + (t[o + 1] << 8 & 65280) + (255 & t[o + 2]),i.push(a(r));return i.join('')}function a(t) { //用到了lreturn l[t >> 18 & 63] + l[t >> 12 & 63] + l[t >> 6 & 63] + l[63 & t]
}//l就是A-Za-z0-9+ 生成l
for (var l = [], c = [], f = 'undefined' != typeof Uint8Array ? Uint8Array : Array, d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', h = 0, p = d.length; h < p; ++h) l[h] = d[h],c[d.charCodeAt(h)] = h;
c['-'.charCodeAt(0)] = 62,c['_'.charCodeAt(0)] = 63

综合W函数得到以下js
命名为qimai.js
经过u函数后,便拿到了加密后的o了,剩下的分析便大同小异了,没什么难度了。

function W(t) {//t为排序后url参数值,返回数组t = t.toString()for (var e = [], n = 0; n < t.length; ++n) e.push(255 & t.charCodeAt(n));return e
}//u函数将数组转化为base64
for (var l = [], c = [], f = 'undefined' != typeof Uint8Array ? Uint8Array : Array, d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', h = 0, p = d.length; h < p; ++h) l[h] = d[h],c[d.charCodeAt(h)] = h;
c['-'.charCodeAt(0)] = 62,c['_'.charCodeAt(0)] = 63function a(t) {return l[t >> 18 & 63] + l[t >> 12 & 63] + l[t >> 6 & 63] + l[63 & t]
}function s(t, e, n) {for (var r, i = [], o = e; o < n; o += 3) r = (t[o] << 16 & 16711680) + (t[o + 1] << 8 & 65280) + (255 & t[o + 2]),i.push(a(r));return i.join('')
}function u(t) {for (var e, n = t.length, r = n % 3, i = '', o = [], a = 16383, u = 0, c = n - r; u < c; u += a) o.push(s(t, u, u + a > c ? c : u + a));return 1 === r ? (e = t[n - 1], i += l[e >> 2], i += l[e << 4 & 63], i += '==') : 2 === r && (e = (t[n - 2] << 8) + t[n - 1], i += l[e >> 10], i += l[e >> 4 & 63], i += l[e << 2 & 63], i += '='),o.push(i),o.join('')
}//直接传入排序后的url参数值,返回base64
function decrypt(o) {return u(W(o))
}

下边附上Python完整版本Demo

import execjs
import timeclass Decrypt():def __init__(self):js_path = ’qimai.js'  #上述的qimai.jsf = open(js_path)js = f.read()self.ctx = execjs.compile(js)f.close()def __f(self, a):'''解密第一步:param a::return:'''e = 'a12c0fa6ab9119bc90e4ac7700796a53'a = list(a)for i in range(len(a)):a[i] = chr(ord(a[i]) ^ ord(e[i % len(e)]))return ''.join(a)@classmethoddef decrypt(cls, tags, params={}):''':param tags: url的分类 如应用宝页面 https://www.qimai.cn/rank/marketRank  则传入rank/marketRank:return:'''self = cls()now_date = round(time.time() * 1000)t = now_date - 708 - 1515125653845params_ = ''if params:o_ = ''.join(sorted(list(params.values())))params_ = self.ctx.call('decrypt', o_)o = '%s@#/%s@#%s@#1' % (params_, tags, t)s = self.__f(o)analysis = self.ctx.call('decrypt', s)return analysisif __name__ == '__main__':now_date = time.strftime('%Y-%m-%d', time.localtime())params_list = [('rank/marketRank', {'market': '1', 'category': '6', 'date': now_date}, '360'),('rank/marketRank', {'market': '3', 'category': '-2', 'date': now_date}, '应用宝'),('rank/marketRank', {'market': '5', 'category': '5', 'date': now_date}, '豌豆荚'),('rank/marketRank', {'market': '4', 'category': '6', 'date': now_date}, '小米'),('rank/marketRank', {'market': '7', 'category': '7', 'date': now_date}, '魅族'),('rank/marketRank', {'market': '9', 'category': '4', 'date': now_date}, 'oppo'),('rank/release', {'genre': '36', 'date': now_date}, 'App Store')]for tags, params, store in params_list:analysis = Decrypt.decrypt(tags, params)print(analysis)

明天附上github

js逆向分析实战之七麦数据相关推荐

  1. 最新战火互娱JS逆向分析实战教程

    目标网址:https://passport.kongzhong.com/ 重要说明:文章教程仅供参考学习,请勿用于非法用途,否则后果自负. 目录 一.接口参数分析

  2. 最新中烟新商盟JS逆向分析实战教程

    目标网址:https://xinshangmeng.com/ 重要说明:文章教程仅供参考学习,请勿用于非法用途,否则后果自负. 目录 一.接口参数分析 二.全局搜索j_mcmm关键词</

  3. JS逆向分析新浪某站登录处RSA加密

    文章目录 前言 RSA加解密 核心思想 Pyhon实现 NoPadding 新浪网实战 JS加密分析 JS函数调试 Py调用脚本 BurCrypto爆破 插件介绍 实战案例 总结 前言 在渗透测试过程 ...

  4. Linux Security Module逆向分析实战

    Linux Security Module逆向分析实战 本文记录了对某发行版Linux中一个安全模块(LSM)的逆向过程,该LSM对系统中待运行的程序进行安全校验,数据流穿越内核态与用户态,涉及系统内 ...

  5. 轻JS逆向分析“攒经验”项目之某交易所Sign加密参数逆向分析

    最近忙着在搞大数据相关的东西,没什么太多时间去研究复杂的JS,所以给大家来几个练手的网站"攒攒经验"吧!这次出的系列是<轻JS逆向分析"攒经验"项目> ...

  6. JS逆向 -- 分析某站aid、cid、w_rid和sid的加密过程

    接上节课内容 JS逆向 -- 分析某站buvid3和_uuid的加密过程 JS逆向 -- 分析某站b_lsid值加密过程 一.清除cookie信息,刷新网页,ctrl+f搜索sid,这样找到的数据是在 ...

  7. QAX答题页面js逆向分析(二)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.通过前端js解密,获取答案 二.通过Python,模拟请求完成自登录到答题的所有操作. 1.引入库 2. 程序结构 ...

  8. R语言时间序列(time series)分析实战:时序数据加载、绘制时间序列图

    R语言时间序列(time series)分析实战:时序数据加载.绘制时间序列图 目录

  9. js aes加密_某高考咨询网js逆向分析笔记

    一.某高考资讯网逆向分析 某网站的js加密分析,安全签名signsafe + HmacSHA1 + AES 一年前分析过网站数据还没有加密,最近需要获取新的数据发现原先的爬虫失效,请求和响应都经过加密 ...

最新文章

  1. (转)一个as3写的减速效果
  2. 关系型数据库的ACID规则
  3. 这是时间的推移 不是系统的分类
  4. CRF++使用简介(windows下非接口)
  5. C语言深度剖析书籍学习记录 第三章 预处理
  6. 第三章 熟悉常用的HDFS操作
  7. 这就是即将发布的苹果刘海屏MacBook Pro样机?
  8. Mac更新之后使用终端提示:The default interactive shell is now zsh.
  9. SPIRE.DOC - .NET开发者的福利
  10. 720. 词典中最长的单词
  11. leetcode Largest Rectangle in Histogram 单调栈
  12. Python入门学习三
  13. python颜色识别,46行代码实现865种颜色识别,看过的都说顶呱呱!
  14. 如何解决back order中,confirmed qty can't be change的问题
  15. HDMI EDID详细解析
  16. linux 无线网卡 频段,Linux 网卡配置 (频段、发射功率等)
  17. c语言中千分号的用法,在ChemDraw中输入千分号的教程
  18. 日语动词+动词类型+动词活用
  19. 跟这台计算机连接的一个USB设备运行不正常,Windows无法识别
  20. xgboost的调优

热门文章

  1. FastReport.Net 版本2019.3.5 免安装--连接数据源
  2. Mobility Radeon HD 4530 @ubuntu20.04 显卡驱动不支持[GPU无法使用]
  3. python爬取全国各级行政区域
  4. 二维码被扫实时返回方案 1
  5. Linux 中的zip命令使用
  6. 超详细的simulink代码生成
  7. ubuntu ufw 配置
  8. MongoDB爬虫实践:虎扑论坛
  9. 富达国际加密货币交易与存储平台目前进入最终测试
  10. tcp通信数据黏包和数据丢失问题